18#include "llvm/IR/IntrinsicsRISCV.h"
25#define DEBUG_TYPE "riscvtti"
28 "riscv-v-register-bit-width-lmul",
30 "The LMUL to use for getRegisterBitWidth queries. Affects LMUL used "
31 "by autovectorized code. Fractional LMULs are not supported."),
37 "Overrides result used for getMaximumVF query which is used "
38 "exclusively by SLP vectorizer."),
43 cl::desc(
"Set the lower bound of a trip count to decide on "
44 "vectorization while tail-folding."),
56 size_t NumInstr = OpCodes.size();
61 return LMULCost * NumInstr;
63 for (
auto Op : OpCodes) {
65 case RISCV::VRGATHER_VI:
68 case RISCV::VRGATHER_VV:
71 case RISCV::VSLIDEUP_VI:
72 case RISCV::VSLIDEDOWN_VI:
75 case RISCV::VSLIDEUP_VX:
76 case RISCV::VSLIDEDOWN_VX:
79 case RISCV::VREDMAX_VS:
80 case RISCV::VREDMIN_VS:
81 case RISCV::VREDMAXU_VS:
82 case RISCV::VREDMINU_VS:
83 case RISCV::VREDSUM_VS:
84 case RISCV::VREDAND_VS:
85 case RISCV::VREDOR_VS:
86 case RISCV::VREDXOR_VS:
87 case RISCV::VFREDMAX_VS:
88 case RISCV::VFREDMIN_VS:
89 case RISCV::VFREDUSUM_VS: {
96 case RISCV::VFREDOSUM_VS: {
105 case RISCV::VFMV_F_S:
106 case RISCV::VFMV_S_F:
108 case RISCV::VMXOR_MM:
109 case RISCV::VMAND_MM:
110 case RISCV::VMANDN_MM:
111 case RISCV::VMNAND_MM:
113 case RISCV::VFIRST_M:
132 assert(Ty->isIntegerTy() &&
133 "getIntImmCost can only estimate cost of materialising integers");
156 if (!BO || !BO->hasOneUse())
159 if (BO->getOpcode() != Instruction::Shl)
170 if (ShAmt == Trailing)
187 if (!Cmp || !Cmp->isEquality())
203 if ((CmpC & Mask) != CmpC)
210 return NewCmpC >= -2048 && NewCmpC <= 2048;
217 assert(Ty->isIntegerTy() &&
218 "getIntImmCost can only estimate cost of materialising integers");
226 bool Takes12BitImm =
false;
227 unsigned ImmArgIdx = ~0U;
230 case Instruction::GetElementPtr:
235 case Instruction::Store: {
240 if (Idx == 1 || !Inst)
245 if (!getTLI()->allowsMemoryAccessForAlignment(
253 case Instruction::Load:
256 case Instruction::And:
258 if (Imm == UINT64_C(0xffff) && ST->hasStdExtZbb())
261 if (Imm == UINT64_C(0xffffffff) &&
262 ((ST->hasStdExtZba() && ST->isRV64()) || ST->isRV32()))
265 if (ST->hasStdExtZbs() && (~Imm).isPowerOf2())
267 if (Inst && Idx == 1 && Imm.getBitWidth() <= ST->getXLen() &&
270 if (Inst && Idx == 1 && Imm.getBitWidth() == 64 &&
273 Takes12BitImm =
true;
275 case Instruction::Add:
276 Takes12BitImm =
true;
278 case Instruction::Or:
279 case Instruction::Xor:
281 if (ST->hasStdExtZbs() && Imm.isPowerOf2())
283 Takes12BitImm =
true;
285 case Instruction::Mul:
287 if (Imm.isPowerOf2() || Imm.isNegatedPowerOf2())
290 if ((Imm + 1).isPowerOf2() || (Imm - 1).isPowerOf2())
293 Takes12BitImm =
true;
295 case Instruction::Sub:
296 case Instruction::Shl:
297 case Instruction::LShr:
298 case Instruction::AShr:
299 Takes12BitImm =
true;
310 if (Imm.getSignificantBits() <= 64 &&
333 return ST->hasVInstructions();
343 unsigned Opcode,
Type *InputTypeA,
Type *InputTypeB,
Type *AccumType,
347 if (Opcode == Instruction::FAdd)
352 if (!ST->hasStdExtZvdot4a8i() || ST->getELen() < 64 ||
353 Opcode != Instruction::Add || !BinOp || *BinOp != Instruction::Mul ||
354 InputTypeA != InputTypeB || !InputTypeA->
isIntegerTy(8) ||
362 getRISCVInstructionCost(RISCV::VDOTA4_VV, LT.second,
CostKind);
369 switch (
II->getIntrinsicID()) {
373 case Intrinsic::vector_reduce_mul:
374 case Intrinsic::vector_reduce_fmul:
380 if (ST->hasVInstructions())
386 if (ST->hasVInstructions())
387 if (
unsigned MinVLen = ST->getRealMinVLen();
402 ST->useRVVForFixedLengthVectors() ? LMUL * ST->getRealMinVLen() : 0);
405 (ST->hasVInstructions() &&
428 return (ST->hasAUIPCADDIFusion() && ST->hasLUIADDIFusion()) ? 1 : 2;
434RISCVTTIImpl::getConstantPoolLoadCost(
Type *Ty,
439 return getStaticDataAddrGenerationCost(
CostKind) +
445 unsigned Size = Mask.size();
448 for (
unsigned I = 0;
I !=
Size; ++
I) {
449 if (
static_cast<unsigned>(Mask[
I]) ==
I)
455 for (
unsigned J =
I + 1; J !=
Size; ++J)
457 if (
static_cast<unsigned>(Mask[J]) != J %
I)
485 "Expected fixed vector type and non-empty mask");
488 unsigned NumOfDests =
divideCeil(Mask.size(), LegalNumElts);
492 if (NumOfDests <= 1 ||
494 Tp->getElementType()->getPrimitiveSizeInBits() ||
495 LegalNumElts >= Tp->getElementCount().getFixedValue())
498 unsigned VecTySize =
TTI.getDataLayout().getTypeStoreSize(Tp);
501 unsigned NumOfSrcs =
divideCeil(VecTySize, LegalVTSize);
505 unsigned NormalizedVF = LegalNumElts * std::max(NumOfSrcs, NumOfDests);
506 unsigned NumOfSrcRegs = NormalizedVF / LegalNumElts;
507 unsigned NumOfDestRegs = NormalizedVF / LegalNumElts;
509 assert(NormalizedVF >= Mask.size() &&
510 "Normalized mask expected to be not shorter than original mask.");
515 NormalizedMask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, []() {},
516 [&](
ArrayRef<int> RegMask,
unsigned SrcReg,
unsigned DestReg) {
519 if (!ReusedSingleSrcShuffles.
insert(std::make_pair(RegMask, SrcReg))
522 Cost +=
TTI.getShuffleCost(
525 SingleOpTy, RegMask,
CostKind, 0,
nullptr);
527 [&](
ArrayRef<int> RegMask,
unsigned Idx1,
unsigned Idx2,
bool NewReg) {
528 Cost +=
TTI.getShuffleCost(
531 SingleOpTy, RegMask,
CostKind, 0,
nullptr);
554 if (!VLen || Mask.empty())
558 LegalVT =
TTI.getTypeLegalizationCost(
564 if (NumOfDests <= 1 ||
566 Tp->getElementType()->getPrimitiveSizeInBits() ||
570 unsigned VecTySize =
TTI.getDataLayout().getTypeStoreSize(Tp);
573 unsigned NumOfSrcs =
divideCeil(VecTySize, LegalVTSize);
579 unsigned NormalizedVF =
584 assert(NormalizedVF >= Mask.size() &&
585 "Normalized mask expected to be not shorter than original mask.");
591 NormalizedMask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, []() {},
592 [&](
ArrayRef<int> RegMask,
unsigned SrcReg,
unsigned DestReg) {
595 if (!ReusedSingleSrcShuffles.
insert(std::make_pair(RegMask, SrcReg))
600 SingleOpTy, RegMask,
CostKind, 0,
nullptr);
602 [&](
ArrayRef<int> RegMask,
unsigned Idx1,
unsigned Idx2,
bool NewReg) {
604 SingleOpTy, RegMask,
CostKind, 0,
nullptr);
611 if ((NumOfDestRegs > 2 && NumShuffles <=
static_cast<int>(NumOfDestRegs)) ||
612 (NumOfDestRegs <= 2 && NumShuffles < 4))
627 if (!
LT.second.isFixedLengthVector())
635 auto GetSlideOpcode = [&](
int SlideAmt) {
637 bool IsVI =
isUInt<5>(std::abs(SlideAmt));
639 return IsVI ? RISCV::VSLIDEDOWN_VI : RISCV::VSLIDEDOWN_VX;
640 return IsVI ? RISCV::VSLIDEUP_VI : RISCV::VSLIDEUP_VX;
643 std::array<std::pair<int, int>, 2> SrcInfo;
647 if (SrcInfo[1].second == 0)
651 if (SrcInfo[0].second != 0) {
652 unsigned Opcode = GetSlideOpcode(SrcInfo[0].second);
653 FirstSlideCost = getRISCVInstructionCost(Opcode,
LT.second,
CostKind);
656 if (SrcInfo[1].first == -1)
657 return FirstSlideCost;
660 if (SrcInfo[1].second != 0) {
661 unsigned Opcode = GetSlideOpcode(SrcInfo[1].second);
662 SecondSlideCost = getRISCVInstructionCost(Opcode,
LT.second,
CostKind);
665 getRISCVInstructionCost(RISCV::VMERGE_VVM,
LT.second,
CostKind);
672 return FirstSlideCost + SecondSlideCost + MaskCost;
683 "Expected the Mask to match the return size if given");
685 "Expected the same scalar types");
694 FVTp && ST->hasVInstructions() && LT.second.isFixedLengthVector()) {
696 *
this, LT.second, ST->getRealVLen(),
698 if (VRegSplittingCost.
isValid())
699 return VRegSplittingCost;
704 if (Mask.size() >= 2) {
705 MVT EltTp = LT.second.getVectorElementType();
716 return 2 * LT.first * TLI->getLMULCost(LT.second);
718 if (Mask[0] == 0 || Mask[0] == 1) {
722 if (
equal(DeinterleaveMask, Mask))
723 return LT.first * getRISCVInstructionCost(RISCV::VNSRL_WI,
728 if (LT.second.getScalarSizeInBits() != 1 &&
731 unsigned NumSlides =
Log2_32(Mask.size() / SubVectorSize);
733 for (
unsigned I = 0;
I != NumSlides; ++
I) {
734 unsigned InsertIndex = SubVectorSize * (1 <<
I);
739 std::pair<InstructionCost, MVT> DestLT =
744 Cost += DestLT.first * TLI->getLMULCost(DestLT.second);
758 if (LT.first == 1 && (LT.second.getScalarSizeInBits() != 8 ||
759 LT.second.getVectorNumElements() <= 256)) {
764 getRISCVInstructionCost(RISCV::VRGATHER_VV, LT.second,
CostKind);
778 if (LT.first == 1 && (LT.second.getScalarSizeInBits() != 8 ||
779 LT.second.getVectorNumElements() <= 256)) {
780 auto &
C = SrcTy->getContext();
781 auto EC = SrcTy->getElementCount();
786 return 2 * IndexCost +
787 getRISCVInstructionCost({RISCV::VRGATHER_VV, RISCV::VRGATHER_VV},
806 if (!Mask.empty() && LT.first.isValid() && LT.first != 1 &&
834 SubLT.second.isValid() && SubLT.second.isFixedLengthVector()) {
835 if (std::optional<unsigned> VLen = ST->getRealVLen();
836 VLen && SubLT.second.getScalarSizeInBits() * Index % *VLen == 0 &&
837 SubLT.second.getSizeInBits() <= *VLen)
845 getRISCVInstructionCost(RISCV::VSLIDEDOWN_VI, LT.second,
CostKind);
852 getRISCVInstructionCost(RISCV::VSLIDEUP_VI, LT.second,
CostKind);
864 (1 + getRISCVInstructionCost({RISCV::VMV_S_X, RISCV::VMERGE_VVM},
869 Instruction::InsertElement);
870 if (LT.second.getScalarSizeInBits() == 1) {
878 (1 + getRISCVInstructionCost({RISCV::VMV_V_X, RISCV::VMSNE_VI},
891 (1 + getRISCVInstructionCost({RISCV::VMV_V_I, RISCV::VMERGE_VIM,
892 RISCV::VMV_X_S, RISCV::VMV_V_X,
901 getRISCVInstructionCost(RISCV::VMV_V_X, LT.second,
CostKind);
907 getRISCVInstructionCost(RISCV::VRGATHER_VI, LT.second,
CostKind);
913 unsigned Opcodes[2] = {RISCV::VSLIDEDOWN_VX, RISCV::VSLIDEUP_VX};
914 if (Index >= 0 && Index < 32)
915 Opcodes[0] = RISCV::VSLIDEDOWN_VI;
916 else if (Index < 0 && Index > -32)
917 Opcodes[1] = RISCV::VSLIDEUP_VI;
918 return LT.first * getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
922 if (!LT.second.isVector())
928 if (SrcTy->getElementType()->isIntegerTy(1)) {
940 MVT ContainerVT = LT.second;
941 if (LT.second.isFixedLengthVector())
942 ContainerVT = TLI->getContainerForFixedLengthVector(LT.second);
944 if (ContainerVT.
bitsLE(M1VT)) {
954 if (LT.second.isFixedLengthVector())
956 LenCost =
isInt<5>(LT.second.getVectorNumElements() - 1) ? 0 : 1;
957 unsigned Opcodes[] = {RISCV::VID_V, RISCV::VRSUB_VX, RISCV::VRGATHER_VV};
958 if (LT.second.isFixedLengthVector() &&
959 isInt<5>(LT.second.getVectorNumElements() - 1))
960 Opcodes[1] = RISCV::VRSUB_VI;
962 getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
963 return LT.first * (LenCost + GatherCost);
970 unsigned M1Opcodes[] = {RISCV::VID_V, RISCV::VRSUB_VX};
972 getRISCVInstructionCost(M1Opcodes, M1VT,
CostKind) + 3;
976 getRISCVInstructionCost({RISCV::VRGATHER_VV}, M1VT,
CostKind) * Ratio;
978 getRISCVInstructionCost({RISCV::VSLIDEDOWN_VX}, LT.second,
CostKind);
979 return FixedCost + LT.first * (GatherCost + SlideCost);
1013 Ty, DemandedElts, Insert, Extract,
CostKind);
1015 if (Insert && !Extract && LT.first.isValid() && LT.second.isVector()) {
1016 if (Ty->getScalarSizeInBits() == 1) {
1026 assert(LT.second.isFixedLengthVector());
1027 MVT ContainerVT = TLI->getContainerForFixedLengthVector(LT.second);
1031 getRISCVInstructionCost(RISCV::VSLIDE1DOWN_VX, LT.second,
CostKind);
1044 switch (MICA.
getID()) {
1045 case Intrinsic::vp_load_ff: {
1046 EVT DataTypeVT = TLI->getValueType(
DL, DataTy);
1047 if (!TLI->isLegalFirstFaultLoad(DataTypeVT, Alignment))
1054 case Intrinsic::experimental_vp_strided_load:
1055 case Intrinsic::experimental_vp_strided_store:
1057 case Intrinsic::masked_compressstore:
1058 case Intrinsic::masked_expandload:
1060 case Intrinsic::vp_scatter:
1061 case Intrinsic::vp_gather:
1062 case Intrinsic::masked_scatter:
1063 case Intrinsic::masked_gather:
1065 case Intrinsic::vp_load:
1066 case Intrinsic::vp_store:
1067 case Intrinsic::masked_load:
1068 case Intrinsic::masked_store:
1077 unsigned Opcode = MICA.
getID() == Intrinsic::masked_load ? Instruction::Load
1078 : Instruction::Store;
1093 bool UseMaskForCond,
bool UseMaskForGaps)
const {
1099 if (!UseMaskForGaps && Factor <= TLI->getMaxSupportedInterleaveFactor()) {
1103 if (LT.second.isVector()) {
1106 VTy->getElementCount().divideCoefficientBy(Factor));
1107 if (VTy->getElementCount().isKnownMultipleOf(Factor) &&
1108 TLI->isLegalInterleavedAccessType(SubVecTy, Factor, Alignment,
1113 if (ST->hasOptimizedSegmentLoadStore(Factor)) {
1116 MVT SubVecVT = getTLI()->getValueType(
DL, SubVecTy).getSimpleVT();
1117 Cost += Factor * TLI->getLMULCost(SubVecVT);
1118 return LT.first *
Cost;
1125 CostKind, {TTI::OK_AnyValue, TTI::OP_None});
1126 unsigned NumLoads = getEstimatedVLFor(VTy);
1127 return NumLoads * MemOpCost;
1140 unsigned VF = FVTy->getNumElements() / Factor;
1147 if (Opcode == Instruction::Load) {
1149 for (
unsigned Index : Indices) {
1153 Mask.resize(VF * Factor, -1);
1157 Cost += ShuffleCost;
1175 UseMaskForCond, UseMaskForGaps);
1177 assert(Opcode == Instruction::Store &&
"Opcode must be a store");
1184 return MemCost + ShuffleCost;
1191 bool IsLoad = MICA.
getID() == Intrinsic::masked_gather ||
1192 MICA.
getID() == Intrinsic::vp_gather;
1193 unsigned Opcode = IsLoad ? Instruction::Load : Instruction::Store;
1199 if ((Opcode == Instruction::Load &&
1201 (Opcode == Instruction::Store &&
1209 unsigned NumLoads = getEstimatedVLFor(&VTy);
1216 unsigned Opcode = MICA.
getID() == Intrinsic::masked_expandload
1218 : Instruction::Store;
1222 bool IsLegal = (Opcode == Instruction::Store &&
1224 (Opcode == Instruction::Load &&
1248 if (Opcode == Instruction::Store)
1249 Opcodes.
append({RISCV::VCOMPRESS_VM});
1251 Opcodes.
append({RISCV::VSETIVLI, RISCV::VIOTA_M, RISCV::VRGATHER_VV});
1253 LT.first * getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
1260 unsigned Opcode = MICA.
getID() == Intrinsic::experimental_vp_strided_load
1262 : Instruction::Store;
1281 {TTI::OK_AnyValue, TTI::OP_None},
I);
1282 unsigned NumLoads = getEstimatedVLFor(&VTy);
1283 return NumLoads * MemOpCost;
1293 for (
auto *Ty : Tys) {
1294 if (!Ty->isVectorTy())
1308 {Intrinsic::floor, MVT::f32, 9},
1309 {Intrinsic::floor, MVT::f64, 9},
1310 {Intrinsic::ceil, MVT::f32, 9},
1311 {Intrinsic::ceil, MVT::f64, 9},
1312 {Intrinsic::trunc, MVT::f32, 7},
1313 {Intrinsic::trunc, MVT::f64, 7},
1314 {Intrinsic::round, MVT::f32, 9},
1315 {Intrinsic::round, MVT::f64, 9},
1316 {Intrinsic::roundeven, MVT::f32, 9},
1317 {Intrinsic::roundeven, MVT::f64, 9},
1318 {Intrinsic::rint, MVT::f32, 7},
1319 {Intrinsic::rint, MVT::f64, 7},
1320 {Intrinsic::nearbyint, MVT::f32, 9},
1321 {Intrinsic::nearbyint, MVT::f64, 9},
1322 {Intrinsic::bswap, MVT::i16, 3},
1323 {Intrinsic::bswap, MVT::i32, 12},
1324 {Intrinsic::bswap, MVT::i64, 31},
1325 {Intrinsic::vp_bswap, MVT::i16, 3},
1326 {Intrinsic::vp_bswap, MVT::i32, 12},
1327 {Intrinsic::vp_bswap, MVT::i64, 31},
1328 {Intrinsic::vp_fshl, MVT::i8, 7},
1329 {Intrinsic::vp_fshl, MVT::i16, 7},
1330 {Intrinsic::vp_fshl, MVT::i32, 7},
1331 {Intrinsic::vp_fshl, MVT::i64, 7},
1332 {Intrinsic::vp_fshr, MVT::i8, 7},
1333 {Intrinsic::vp_fshr, MVT::i16, 7},
1334 {Intrinsic::vp_fshr, MVT::i32, 7},
1335 {Intrinsic::vp_fshr, MVT::i64, 7},
1336 {Intrinsic::bitreverse, MVT::i8, 17},
1337 {Intrinsic::bitreverse, MVT::i16, 24},
1338 {Intrinsic::bitreverse, MVT::i32, 33},
1339 {Intrinsic::bitreverse, MVT::i64, 52},
1340 {Intrinsic::vp_bitreverse, MVT::i8, 17},
1341 {Intrinsic::vp_bitreverse, MVT::i16, 24},
1342 {Intrinsic::vp_bitreverse, MVT::i32, 33},
1343 {Intrinsic::vp_bitreverse, MVT::i64, 52},
1344 {Intrinsic::ctpop, MVT::i8, 12},
1345 {Intrinsic::ctpop, MVT::i16, 19},
1346 {Intrinsic::ctpop, MVT::i32, 20},
1347 {Intrinsic::ctpop, MVT::i64, 21},
1348 {Intrinsic::ctlz, MVT::i8, 19},
1349 {Intrinsic::ctlz, MVT::i16, 28},
1350 {Intrinsic::ctlz, MVT::i32, 31},
1351 {Intrinsic::ctlz, MVT::i64, 35},
1352 {Intrinsic::cttz, MVT::i8, 16},
1353 {Intrinsic::cttz, MVT::i16, 23},
1354 {Intrinsic::cttz, MVT::i32, 24},
1355 {Intrinsic::cttz, MVT::i64, 25},
1356 {Intrinsic::vp_ctpop, MVT::i8, 12},
1357 {Intrinsic::vp_ctpop, MVT::i16, 19},
1358 {Intrinsic::vp_ctpop, MVT::i32, 20},
1359 {Intrinsic::vp_ctpop, MVT::i64, 21},
1360 {Intrinsic::vp_ctlz, MVT::i8, 19},
1361 {Intrinsic::vp_ctlz, MVT::i16, 28},
1362 {Intrinsic::vp_ctlz, MVT::i32, 31},
1363 {Intrinsic::vp_ctlz, MVT::i64, 35},
1364 {Intrinsic::vp_cttz, MVT::i8, 16},
1365 {Intrinsic::vp_cttz, MVT::i16, 23},
1366 {Intrinsic::vp_cttz, MVT::i32, 24},
1367 {Intrinsic::vp_cttz, MVT::i64, 25},
1374 switch (ICA.
getID()) {
1375 case Intrinsic::lrint:
1376 case Intrinsic::llrint:
1377 case Intrinsic::lround:
1378 case Intrinsic::llround: {
1382 if (ST->hasVInstructions() && LT.second.isVector()) {
1384 unsigned SrcEltSz =
DL.getTypeSizeInBits(SrcTy->getScalarType());
1385 unsigned DstEltSz =
DL.getTypeSizeInBits(RetTy->getScalarType());
1386 if (LT.second.getVectorElementType() == MVT::bf16) {
1387 if (!ST->hasVInstructionsBF16Minimal())
1390 Ops = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFCVT_X_F_V};
1392 Ops = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFWCVT_X_F_V};
1393 }
else if (LT.second.getVectorElementType() == MVT::f16 &&
1394 !ST->hasVInstructionsF16()) {
1395 if (!ST->hasVInstructionsF16Minimal())
1398 Ops = {RISCV::VFWCVT_F_F_V, RISCV::VFCVT_X_F_V};
1400 Ops = {RISCV::VFWCVT_F_F_V, RISCV::VFWCVT_X_F_V};
1402 }
else if (SrcEltSz > DstEltSz) {
1403 Ops = {RISCV::VFNCVT_X_F_W};
1404 }
else if (SrcEltSz < DstEltSz) {
1405 Ops = {RISCV::VFWCVT_X_F_V};
1407 Ops = {RISCV::VFCVT_X_F_V};
1412 if (SrcEltSz > DstEltSz)
1413 return SrcLT.first *
1414 getRISCVInstructionCost(
Ops, SrcLT.second,
CostKind);
1415 return LT.first * getRISCVInstructionCost(
Ops, LT.second,
CostKind);
1419 case Intrinsic::ceil:
1420 case Intrinsic::floor:
1421 case Intrinsic::trunc:
1422 case Intrinsic::rint:
1423 case Intrinsic::round:
1424 case Intrinsic::roundeven: {
1427 if (!LT.second.isVector() && TLI->isOperationCustom(
ISD::FCEIL, LT.second))
1428 return LT.first * 8;
1431 case Intrinsic::umin:
1432 case Intrinsic::umax:
1433 case Intrinsic::smin:
1434 case Intrinsic::smax: {
1436 if (LT.second.isScalarInteger() && ST->hasStdExtZbb())
1439 if (ST->hasVInstructions() && LT.second.isVector()) {
1441 switch (ICA.
getID()) {
1442 case Intrinsic::umin:
1443 Op = RISCV::VMINU_VV;
1445 case Intrinsic::umax:
1446 Op = RISCV::VMAXU_VV;
1448 case Intrinsic::smin:
1449 Op = RISCV::VMIN_VV;
1451 case Intrinsic::smax:
1452 Op = RISCV::VMAX_VV;
1455 return LT.first * getRISCVInstructionCost(
Op, LT.second,
CostKind);
1459 case Intrinsic::sadd_sat:
1460 case Intrinsic::ssub_sat:
1461 case Intrinsic::uadd_sat:
1462 case Intrinsic::usub_sat: {
1464 if (ST->hasVInstructions() && LT.second.isVector()) {
1466 switch (ICA.
getID()) {
1467 case Intrinsic::sadd_sat:
1468 Op = RISCV::VSADD_VV;
1470 case Intrinsic::ssub_sat:
1471 Op = RISCV::VSSUBU_VV;
1473 case Intrinsic::uadd_sat:
1474 Op = RISCV::VSADDU_VV;
1476 case Intrinsic::usub_sat:
1477 Op = RISCV::VSSUBU_VV;
1480 return LT.first * getRISCVInstructionCost(
Op, LT.second,
CostKind);
1484 case Intrinsic::fma:
1485 case Intrinsic::fmuladd: {
1488 if (ST->hasVInstructions() && LT.second.isVector())
1490 getRISCVInstructionCost(RISCV::VFMADD_VV, LT.second,
CostKind);
1493 case Intrinsic::fabs: {
1495 if (ST->hasVInstructions() && LT.second.isVector()) {
1501 if (LT.second.getVectorElementType() == MVT::bf16 ||
1502 (LT.second.getVectorElementType() == MVT::f16 &&
1503 !ST->hasVInstructionsF16()))
1504 return LT.first * getRISCVInstructionCost(RISCV::VAND_VX, LT.second,
1509 getRISCVInstructionCost(RISCV::VFSGNJX_VV, LT.second,
CostKind);
1513 case Intrinsic::sqrt: {
1515 if (ST->hasVInstructions() && LT.second.isVector()) {
1518 MVT ConvType = LT.second;
1519 MVT FsqrtType = LT.second;
1522 if (LT.second.getVectorElementType() == MVT::bf16) {
1523 if (LT.second == MVT::nxv32bf16) {
1524 ConvOp = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFWCVTBF16_F_F_V,
1525 RISCV::VFNCVTBF16_F_F_W, RISCV::VFNCVTBF16_F_F_W};
1526 FsqrtOp = {RISCV::VFSQRT_V, RISCV::VFSQRT_V};
1527 ConvType = MVT::nxv16f16;
1528 FsqrtType = MVT::nxv16f32;
1530 ConvOp = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFNCVTBF16_F_F_W};
1531 FsqrtOp = {RISCV::VFSQRT_V};
1532 FsqrtType = TLI->getTypeToPromoteTo(
ISD::FSQRT, FsqrtType);
1534 }
else if (LT.second.getVectorElementType() == MVT::f16 &&
1535 !ST->hasVInstructionsF16()) {
1536 if (LT.second == MVT::nxv32f16) {
1537 ConvOp = {RISCV::VFWCVT_F_F_V, RISCV::VFWCVT_F_F_V,
1538 RISCV::VFNCVT_F_F_W, RISCV::VFNCVT_F_F_W};
1539 FsqrtOp = {RISCV::VFSQRT_V, RISCV::VFSQRT_V};
1540 ConvType = MVT::nxv16f16;
1541 FsqrtType = MVT::nxv16f32;
1543 ConvOp = {RISCV::VFWCVT_F_F_V, RISCV::VFNCVT_F_F_W};
1544 FsqrtOp = {RISCV::VFSQRT_V};
1545 FsqrtType = TLI->getTypeToPromoteTo(
ISD::FSQRT, FsqrtType);
1548 FsqrtOp = {RISCV::VFSQRT_V};
1551 return LT.first * (getRISCVInstructionCost(FsqrtOp, FsqrtType,
CostKind) +
1552 getRISCVInstructionCost(ConvOp, ConvType,
CostKind));
1556 case Intrinsic::cttz:
1557 case Intrinsic::ctlz:
1558 case Intrinsic::ctpop: {
1560 if (ST->hasStdExtZvbb() && LT.second.isVector()) {
1562 switch (ICA.
getID()) {
1563 case Intrinsic::cttz:
1566 case Intrinsic::ctlz:
1569 case Intrinsic::ctpop:
1570 Op = RISCV::VCPOP_V;
1573 return LT.first * getRISCVInstructionCost(
Op, LT.second,
CostKind);
1577 case Intrinsic::abs: {
1579 if (ST->hasVInstructions() && LT.second.isVector()) {
1581 if (ST->hasStdExtZvabd())
1583 getRISCVInstructionCost({RISCV::VABS_V}, LT.second,
CostKind);
1588 getRISCVInstructionCost({RISCV::VRSUB_VI, RISCV::VMAX_VV},
1593 case Intrinsic::fshl:
1594 case Intrinsic::fshr: {
1601 if ((ST->hasStdExtZbb() || ST->hasStdExtZbkb()) && RetTy->isIntegerTy() &&
1603 (RetTy->getIntegerBitWidth() == 32 ||
1604 RetTy->getIntegerBitWidth() == 64) &&
1605 RetTy->getIntegerBitWidth() <= ST->getXLen()) {
1610 case Intrinsic::get_active_lane_mask: {
1611 if (ST->hasVInstructions()) {
1620 getRISCVInstructionCost({RISCV::VSADDU_VX, RISCV::VMSLTU_VX},
1626 case Intrinsic::stepvector: {
1630 if (ST->hasVInstructions())
1631 return getRISCVInstructionCost(RISCV::VID_V, LT.second,
CostKind) +
1633 getRISCVInstructionCost(RISCV::VADD_VX, LT.second,
CostKind);
1634 return 1 + (LT.first - 1);
1636 case Intrinsic::vector_splice_left:
1637 case Intrinsic::vector_splice_right: {
1642 if (ST->hasVInstructions() && LT.second.isVector()) {
1644 getRISCVInstructionCost({RISCV::VSLIDEDOWN_VX, RISCV::VSLIDEUP_VX},
1649 case Intrinsic::experimental_cttz_elts: {
1651 EVT ArgType = TLI->getValueType(
DL, ArgTy,
true);
1652 if (getTLI()->shouldExpandCttzElements(ArgType))
1669 case Intrinsic::experimental_vp_splice: {
1677 case Intrinsic::fptoui_sat:
1678 case Intrinsic::fptosi_sat: {
1680 bool IsSigned = ICA.
getID() == Intrinsic::fptosi_sat;
1685 if (!SrcTy->isVectorTy())
1688 if (!SrcLT.first.isValid() || !DstLT.first.isValid())
1707 if (ST->hasVInstructions() && RetTy->isVectorTy()) {
1709 LT.second.isVector()) {
1710 MVT EltTy = LT.second.getVectorElementType();
1712 ICA.
getID(), EltTy))
1713 return LT.first * Entry->Cost;
1726 if (ST->hasVInstructions() && PtrTy->
isVectorTy())
1744 if (ST->hasStdExtP() &&
1752 if (!ST->hasVInstructions() || Src->getScalarSizeInBits() > ST->getELen() ||
1753 Dst->getScalarSizeInBits() > ST->getELen())
1756 int ISD = TLI->InstructionOpcodeToISD(Opcode);
1771 if (Src->getScalarSizeInBits() == 1) {
1776 return getRISCVInstructionCost(RISCV::VMV_V_I, DstLT.second,
CostKind) +
1777 DstLT.first * getRISCVInstructionCost(RISCV::VMERGE_VIM,
1783 if (Dst->getScalarSizeInBits() == 1) {
1789 return SrcLT.first *
1790 getRISCVInstructionCost({RISCV::VAND_VI, RISCV::VMSNE_VI},
1802 if (!SrcLT.second.isVector() || !DstLT.second.isVector() ||
1803 !SrcLT.first.isValid() || !DstLT.first.isValid() ||
1805 SrcLT.second.getSizeInBits()) ||
1807 DstLT.second.getSizeInBits()) ||
1808 SrcLT.first > 1 || DstLT.first > 1)
1812 assert((SrcLT.first == 1) && (DstLT.first == 1) &&
"Illegal type");
1814 int PowDiff = (int)
Log2_32(DstLT.second.getScalarSizeInBits()) -
1815 (int)
Log2_32(SrcLT.second.getScalarSizeInBits());
1819 if ((PowDiff < 1) || (PowDiff > 3))
1821 unsigned SExtOp[] = {RISCV::VSEXT_VF2, RISCV::VSEXT_VF4, RISCV::VSEXT_VF8};
1822 unsigned ZExtOp[] = {RISCV::VZEXT_VF2, RISCV::VZEXT_VF4, RISCV::VZEXT_VF8};
1825 return getRISCVInstructionCost(
Op, DstLT.second,
CostKind);
1831 unsigned SrcEltSize = SrcLT.second.getScalarSizeInBits();
1832 unsigned DstEltSize = DstLT.second.getScalarSizeInBits();
1836 : RISCV::VFNCVT_F_F_W;
1838 for (; SrcEltSize != DstEltSize;) {
1842 MVT DstMVT = DstLT.second.changeVectorElementType(ElementMVT);
1844 (DstEltSize > SrcEltSize) ? DstEltSize >> 1 : DstEltSize << 1;
1852 unsigned FCVT = IsSigned ? RISCV::VFCVT_RTZ_X_F_V : RISCV::VFCVT_RTZ_XU_F_V;
1854 IsSigned ? RISCV::VFWCVT_RTZ_X_F_V : RISCV::VFWCVT_RTZ_XU_F_V;
1856 IsSigned ? RISCV::VFNCVT_RTZ_X_F_W : RISCV::VFNCVT_RTZ_XU_F_W;
1857 unsigned SrcEltSize = Src->getScalarSizeInBits();
1858 unsigned DstEltSize = Dst->getScalarSizeInBits();
1860 if ((SrcEltSize == 16) &&
1861 (!ST->hasVInstructionsF16() || ((DstEltSize / 2) > SrcEltSize))) {
1867 std::pair<InstructionCost, MVT> VecF32LT =
1870 VecF32LT.first * getRISCVInstructionCost(RISCV::VFWCVT_F_F_V,
1875 if (DstEltSize == SrcEltSize)
1876 Cost += getRISCVInstructionCost(FCVT, DstLT.second,
CostKind);
1877 else if (DstEltSize > SrcEltSize)
1878 Cost += getRISCVInstructionCost(FWCVT, DstLT.second,
CostKind);
1883 MVT VecVT = DstLT.second.changeVectorElementType(ElementVT);
1884 Cost += getRISCVInstructionCost(FNCVT, VecVT,
CostKind);
1885 if ((SrcEltSize / 2) > DstEltSize) {
1896 unsigned FCVT = IsSigned ? RISCV::VFCVT_F_X_V : RISCV::VFCVT_F_XU_V;
1897 unsigned FWCVT = IsSigned ? RISCV::VFWCVT_F_X_V : RISCV::VFWCVT_F_XU_V;
1898 unsigned FNCVT = IsSigned ? RISCV::VFNCVT_F_X_W : RISCV::VFNCVT_F_XU_W;
1899 unsigned SrcEltSize = Src->getScalarSizeInBits();
1900 unsigned DstEltSize = Dst->getScalarSizeInBits();
1903 if ((DstEltSize == 16) &&
1904 (!ST->hasVInstructionsF16() || ((SrcEltSize / 2) > DstEltSize))) {
1910 std::pair<InstructionCost, MVT> VecF32LT =
1913 Cost += VecF32LT.first * getRISCVInstructionCost(RISCV::VFNCVT_F_F_W,
1918 if (DstEltSize == SrcEltSize)
1919 Cost += getRISCVInstructionCost(FCVT, DstLT.second,
CostKind);
1920 else if (DstEltSize > SrcEltSize) {
1921 if ((DstEltSize / 2) > SrcEltSize) {
1925 unsigned Op = IsSigned ? Instruction::SExt : Instruction::ZExt;
1928 Cost += getRISCVInstructionCost(FWCVT, DstLT.second,
CostKind);
1930 Cost += getRISCVInstructionCost(FNCVT, DstLT.second,
CostKind);
1937unsigned RISCVTTIImpl::getEstimatedVLFor(
VectorType *Ty)
const {
1939 const unsigned EltSize =
DL.getTypeSizeInBits(Ty->getElementType());
1940 const unsigned MinSize =
DL.getTypeSizeInBits(Ty).getKnownMinValue();
1955 if (Ty->getScalarSizeInBits() > ST->getELen())
1959 if (Ty->getElementType()->isIntegerTy(1)) {
1963 if (IID == Intrinsic::umax || IID == Intrinsic::smin)
1969 if (IID == Intrinsic::maximum || IID == Intrinsic::minimum) {
1973 case Intrinsic::maximum:
1975 Opcodes = {RISCV::VFREDMAX_VS, RISCV::VFMV_F_S};
1977 Opcodes = {RISCV::VMFNE_VV, RISCV::VCPOP_M, RISCV::VFREDMAX_VS,
1992 case Intrinsic::minimum:
1994 Opcodes = {RISCV::VFREDMIN_VS, RISCV::VFMV_F_S};
1996 Opcodes = {RISCV::VMFNE_VV, RISCV::VCPOP_M, RISCV::VFREDMIN_VS,
2002 const unsigned EltTyBits =
DL.getTypeSizeInBits(DstTy);
2011 return ExtraCost + getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2020 case Intrinsic::smax:
2021 SplitOp = RISCV::VMAX_VV;
2022 Opcodes = {RISCV::VREDMAX_VS, RISCV::VMV_X_S};
2024 case Intrinsic::smin:
2025 SplitOp = RISCV::VMIN_VV;
2026 Opcodes = {RISCV::VREDMIN_VS, RISCV::VMV_X_S};
2028 case Intrinsic::umax:
2029 SplitOp = RISCV::VMAXU_VV;
2030 Opcodes = {RISCV::VREDMAXU_VS, RISCV::VMV_X_S};
2032 case Intrinsic::umin:
2033 SplitOp = RISCV::VMINU_VV;
2034 Opcodes = {RISCV::VREDMINU_VS, RISCV::VMV_X_S};
2036 case Intrinsic::maxnum:
2037 SplitOp = RISCV::VFMAX_VV;
2038 Opcodes = {RISCV::VFREDMAX_VS, RISCV::VFMV_F_S};
2040 case Intrinsic::minnum:
2041 SplitOp = RISCV::VFMIN_VV;
2042 Opcodes = {RISCV::VFREDMIN_VS, RISCV::VFMV_F_S};
2047 (LT.first > 1) ? (LT.first - 1) *
2048 getRISCVInstructionCost(SplitOp, LT.second,
CostKind)
2050 return SplitCost + getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2055 std::optional<FastMathFlags> FMF,
2061 if (Ty->getScalarSizeInBits() > ST->getELen())
2064 int ISD = TLI->InstructionOpcodeToISD(Opcode);
2072 Type *ElementTy = Ty->getElementType();
2077 if (LT.second == MVT::v1i1)
2078 return getRISCVInstructionCost(RISCV::VFIRST_M, LT.second,
CostKind) +
2096 return ((LT.first > 2) ? (LT.first - 2) : 0) *
2097 getRISCVInstructionCost(RISCV::VMAND_MM, LT.second,
CostKind) +
2098 getRISCVInstructionCost(RISCV::VMNAND_MM, LT.second,
CostKind) +
2099 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind) +
2108 return (LT.first - 1) *
2109 getRISCVInstructionCost(RISCV::VMXOR_MM, LT.second,
CostKind) +
2110 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind) + 1;
2118 return (LT.first - 1) *
2119 getRISCVInstructionCost(RISCV::VMOR_MM, LT.second,
CostKind) +
2120 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind) +
2133 SplitOp = RISCV::VADD_VV;
2134 Opcodes = {RISCV::VMV_S_X, RISCV::VREDSUM_VS, RISCV::VMV_X_S};
2137 SplitOp = RISCV::VOR_VV;
2138 Opcodes = {RISCV::VREDOR_VS, RISCV::VMV_X_S};
2141 SplitOp = RISCV::VXOR_VV;
2142 Opcodes = {RISCV::VMV_S_X, RISCV::VREDXOR_VS, RISCV::VMV_X_S};
2145 SplitOp = RISCV::VAND_VV;
2146 Opcodes = {RISCV::VREDAND_VS, RISCV::VMV_X_S};
2150 if ((LT.second.getScalarType() == MVT::f16 && !ST->hasVInstructionsF16()) ||
2151 LT.second.getScalarType() == MVT::bf16)
2155 for (
unsigned i = 0; i < LT.first.getValue(); i++)
2158 return getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2160 SplitOp = RISCV::VFADD_VV;
2161 Opcodes = {RISCV::VFMV_S_F, RISCV::VFREDUSUM_VS, RISCV::VFMV_F_S};
2166 (LT.first > 1) ? (LT.first - 1) *
2167 getRISCVInstructionCost(SplitOp, LT.second,
CostKind)
2169 return SplitCost + getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2173 unsigned Opcode,
bool IsUnsigned,
Type *ResTy,
VectorType *ValTy,
2184 if (Opcode != Instruction::Add && Opcode != Instruction::FAdd)
2190 if (IsUnsigned && Opcode == Instruction::Add &&
2191 LT.second.isFixedLengthVector() && LT.second.getScalarType() == MVT::i1) {
2195 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind);
2202 return (LT.first - 1) +
2209 assert(OpInfo.isConstant() &&
"non constant operand?");
2216 if (OpInfo.isUniform())
2222 return getConstantPoolLoadCost(Ty,
CostKind);
2231 EVT VT = TLI->getValueType(
DL, Src,
true);
2233 if (VT == MVT::Other)
2238 if (Opcode == Instruction::Store && OpInfo.isConstant())
2253 if (Src->
isVectorTy() && LT.second.isVector() &&
2255 LT.second.getSizeInBits()))
2265 if (ST->hasVInstructions() && LT.second.isVector() &&
2267 BaseCost *= TLI->getLMULCost(LT.second);
2268 return Cost + BaseCost;
2277 Op1Info, Op2Info,
I);
2281 Op1Info, Op2Info,
I);
2284 if (ValTy->isVectorTy() && ValTy->getScalarSizeInBits() > ST->getELen())
2286 Op1Info, Op2Info,
I);
2288 auto GetConstantMatCost =
2290 if (OpInfo.isUniform())
2295 return getConstantPoolLoadCost(ValTy,
CostKind);
2300 ConstantMatCost += GetConstantMatCost(Op1Info);
2302 ConstantMatCost += GetConstantMatCost(Op2Info);
2305 if (Opcode == Instruction::Select && ValTy->isVectorTy()) {
2307 if (ValTy->getScalarSizeInBits() == 1) {
2311 return ConstantMatCost +
2313 getRISCVInstructionCost(
2314 {RISCV::VMANDN_MM, RISCV::VMAND_MM, RISCV::VMOR_MM},
2318 return ConstantMatCost +
2319 LT.first * getRISCVInstructionCost(RISCV::VMERGE_VVM, LT.second,
2323 if (ValTy->getScalarSizeInBits() == 1) {
2329 MVT InterimVT = LT.second.changeVectorElementType(MVT::i8);
2330 return ConstantMatCost +
2332 getRISCVInstructionCost({RISCV::VMV_V_X, RISCV::VMSNE_VI},
2334 LT.first * getRISCVInstructionCost(
2335 {RISCV::VMANDN_MM, RISCV::VMAND_MM, RISCV::VMOR_MM},
2342 return ConstantMatCost +
2343 LT.first * getRISCVInstructionCost(
2344 {RISCV::VMV_V_X, RISCV::VMSNE_VI, RISCV::VMERGE_VVM},
2348 if ((Opcode == Instruction::ICmp) && ValTy->isVectorTy() &&
2352 return ConstantMatCost + LT.first * getRISCVInstructionCost(RISCV::VMSLT_VV,
2357 if ((Opcode == Instruction::FCmp) && ValTy->isVectorTy() &&
2362 return ConstantMatCost +
2363 getRISCVInstructionCost(RISCV::VMXOR_MM, LT.second,
CostKind);
2369 if ((ValTy->getScalarSizeInBits() == 16 && !ST->hasVInstructionsF16()) ||
2370 (ValTy->getScalarSizeInBits() == 32 && !ST->hasVInstructionsF32()) ||
2371 (ValTy->getScalarSizeInBits() == 64 && !ST->hasVInstructionsF64()))
2373 Op1Info, Op2Info,
I);
2382 return ConstantMatCost +
2383 LT.first * getRISCVInstructionCost(
2384 {RISCV::VMFLT_VV, RISCV::VMFLT_VV, RISCV::VMOR_MM},
2391 return ConstantMatCost +
2393 getRISCVInstructionCost({RISCV::VMFLT_VV, RISCV::VMNAND_MM},
2402 return ConstantMatCost +
2404 getRISCVInstructionCost(RISCV::VMFLT_VV, LT.second,
CostKind);
2415 ValTy->isIntegerTy() && !
I->user_empty()) {
2417 return match(U, m_Select(m_Specific(I), m_Value(), m_Value())) &&
2418 U->getType()->isIntegerTy() &&
2419 !isa<ConstantData>(U->getOperand(1)) &&
2420 !isa<ConstantData>(U->getOperand(2));
2428 Op1Info, Op2Info,
I);
2435 return Opcode == Instruction::PHI ? 0 : 1;
2452 if (Opcode != Instruction::ExtractElement &&
2453 Opcode != Instruction::InsertElement)
2461 if (!LT.second.isVector()) {
2470 Type *ElemTy = FixedVecTy->getElementType();
2471 auto NumElems = FixedVecTy->getNumElements();
2472 auto Align =
DL.getPrefTypeAlign(ElemTy);
2477 return Opcode == Instruction::ExtractElement
2478 ? StoreCost * NumElems + LoadCost
2479 : (StoreCost + LoadCost) * NumElems + StoreCost;
2483 if (LT.second.isScalableVector() && !LT.first.isValid())
2491 if (Opcode == Instruction::ExtractElement) {
2497 return ExtendCost + ExtractCost;
2507 return ExtendCost + InsertCost + TruncCost;
2513 unsigned BaseCost = 1;
2515 unsigned SlideCost = Opcode == Instruction::InsertElement ? 2 : 1;
2520 if (LT.second.isFixedLengthVector()) {
2521 unsigned Width = LT.second.getVectorNumElements();
2522 Index = Index % Width;
2527 if (
auto VLEN = ST->getRealVLen()) {
2528 unsigned EltSize = LT.second.getScalarSizeInBits();
2529 unsigned M1Max = *VLEN / EltSize;
2530 Index = Index % M1Max;
2536 else if (ST->hasVendorXRivosVisni() &&
isUInt<5>(Index) &&
2539 else if (Opcode == Instruction::InsertElement)
2547 ((Index == -1U) || (Index >= LT.second.getVectorMinNumElements() &&
2548 LT.second.isScalableVector()))) {
2550 Align VecAlign =
DL.getPrefTypeAlign(Val);
2551 Align SclAlign =
DL.getPrefTypeAlign(ScalarType);
2556 if (Opcode == Instruction::ExtractElement)
2592 BaseCost = Opcode == Instruction::InsertElement ? 3 : 4;
2594 return BaseCost + SlideCost;
2600 unsigned Index)
const {
2609 assert(Index < EC.getKnownMinValue() &&
"Unexpected reverse index");
2611 EC.getKnownMinValue() - 1 - Index,
nullptr,
2636 unsigned ISDOpcode = TLI->InstructionOpcodeToISD(Opcode);
2639 if (!LT.second.isVector()) {
2649 if (TLI->isOperationLegalOrPromote(ISDOpcode, LT.second))
2650 if (
const auto *Entry =
CostTableLookup(DivTbl, ISDOpcode, LT.second))
2651 return Entry->Cost * LT.first;
2660 if ((LT.second.getVectorElementType() == MVT::f16 ||
2661 LT.second.getVectorElementType() == MVT::bf16) &&
2662 TLI->getOperationAction(ISDOpcode, LT.second) ==
2664 MVT PromotedVT = TLI->getTypeToPromoteTo(ISDOpcode, LT.second);
2668 CastCost += LT.first * Args.size() *
2676 LT.second = PromotedVT;
2679 auto getConstantMatCost =
2689 return getConstantPoolLoadCost(Ty,
CostKind);
2695 ConstantMatCost += getConstantMatCost(0, Op1Info);
2697 ConstantMatCost += getConstantMatCost(1, Op2Info);
2700 switch (ISDOpcode) {
2703 Op = RISCV::VADD_VV;
2708 Op = RISCV::VSLL_VV;
2713 Op = (Ty->getScalarSizeInBits() == 1) ? RISCV::VMAND_MM : RISCV::VAND_VV;
2718 Op = RISCV::VMUL_VV;
2722 Op = RISCV::VDIV_VV;
2726 Op = RISCV::VREM_VV;
2730 Op = RISCV::VFADD_VV;
2733 Op = RISCV::VFMUL_VV;
2736 Op = RISCV::VFDIV_VV;
2739 Op = RISCV::VFSGNJN_VV;
2744 return CastCost + ConstantMatCost +
2753 if (Ty->isFPOrFPVectorTy())
2755 return CastCost + ConstantMatCost + LT.first *
InstrCost;
2778 if (Info.isSameBase() && V !=
Base) {
2779 if (
GEP->hasAllConstantIndices())
2785 unsigned Stride =
DL.getTypeStoreSize(AccessTy);
2786 if (Info.isUnitStride() &&
2792 GEP->getType()->getPointerAddressSpace()))
2795 {TTI::OK_AnyValue, TTI::OP_None},
2796 {TTI::OK_AnyValue, TTI::OP_None}, {});
2813 if (ST->enableDefaultUnroll())
2823 if (L->getHeader()->getParent()->hasOptSize())
2827 L->getExitingBlocks(ExitingBlocks);
2829 <<
"Blocks: " << L->getNumBlocks() <<
"\n"
2830 <<
"Exit blocks: " << ExitingBlocks.
size() <<
"\n");
2834 if (ExitingBlocks.
size() > 2)
2839 if (L->getNumBlocks() > 4)
2847 for (
auto *BB : L->getBlocks()) {
2848 for (
auto &
I : *BB) {
2852 if (IsVectorized && (
I.getType()->isVectorTy() ||
2854 return V->getType()->isVectorTy();
2895 bool HasMask =
false;
2898 bool IsWrite) -> int64_t {
2899 if (
auto *TarExtTy =
2901 return TarExtTy->getIntParameter(0);
2907 case Intrinsic::riscv_vle_mask:
2908 case Intrinsic::riscv_vse_mask:
2909 case Intrinsic::riscv_vlseg2_mask:
2910 case Intrinsic::riscv_vlseg3_mask:
2911 case Intrinsic::riscv_vlseg4_mask:
2912 case Intrinsic::riscv_vlseg5_mask:
2913 case Intrinsic::riscv_vlseg6_mask:
2914 case Intrinsic::riscv_vlseg7_mask:
2915 case Intrinsic::riscv_vlseg8_mask:
2916 case Intrinsic::riscv_vsseg2_mask:
2917 case Intrinsic::riscv_vsseg3_mask:
2918 case Intrinsic::riscv_vsseg4_mask:
2919 case Intrinsic::riscv_vsseg5_mask:
2920 case Intrinsic::riscv_vsseg6_mask:
2921 case Intrinsic::riscv_vsseg7_mask:
2922 case Intrinsic::riscv_vsseg8_mask:
2925 case Intrinsic::riscv_vle:
2926 case Intrinsic::riscv_vse:
2927 case Intrinsic::riscv_vlseg2:
2928 case Intrinsic::riscv_vlseg3:
2929 case Intrinsic::riscv_vlseg4:
2930 case Intrinsic::riscv_vlseg5:
2931 case Intrinsic::riscv_vlseg6:
2932 case Intrinsic::riscv_vlseg7:
2933 case Intrinsic::riscv_vlseg8:
2934 case Intrinsic::riscv_vsseg2:
2935 case Intrinsic::riscv_vsseg3:
2936 case Intrinsic::riscv_vsseg4:
2937 case Intrinsic::riscv_vsseg5:
2938 case Intrinsic::riscv_vsseg6:
2939 case Intrinsic::riscv_vsseg7:
2940 case Intrinsic::riscv_vsseg8: {
2957 Ty = TarExtTy->getTypeParameter(0U);
2962 const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
2963 unsigned VLIndex = RVVIInfo->VLOperand;
2964 unsigned PtrOperandNo = VLIndex - 1 - HasMask;
2972 unsigned SegNum = getSegNum(Inst, PtrOperandNo, IsWrite);
2975 unsigned ElemSize = Ty->getScalarSizeInBits();
2979 Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty,
2980 Alignment, Mask, EVL);
2983 case Intrinsic::riscv_vlse_mask:
2984 case Intrinsic::riscv_vsse_mask:
2985 case Intrinsic::riscv_vlsseg2_mask:
2986 case Intrinsic::riscv_vlsseg3_mask:
2987 case Intrinsic::riscv_vlsseg4_mask:
2988 case Intrinsic::riscv_vlsseg5_mask:
2989 case Intrinsic::riscv_vlsseg6_mask:
2990 case Intrinsic::riscv_vlsseg7_mask:
2991 case Intrinsic::riscv_vlsseg8_mask:
2992 case Intrinsic::riscv_vssseg2_mask:
2993 case Intrinsic::riscv_vssseg3_mask:
2994 case Intrinsic::riscv_vssseg4_mask:
2995 case Intrinsic::riscv_vssseg5_mask:
2996 case Intrinsic::riscv_vssseg6_mask:
2997 case Intrinsic::riscv_vssseg7_mask:
2998 case Intrinsic::riscv_vssseg8_mask:
3001 case Intrinsic::riscv_vlse:
3002 case Intrinsic::riscv_vsse:
3003 case Intrinsic::riscv_vlsseg2:
3004 case Intrinsic::riscv_vlsseg3:
3005 case Intrinsic::riscv_vlsseg4:
3006 case Intrinsic::riscv_vlsseg5:
3007 case Intrinsic::riscv_vlsseg6:
3008 case Intrinsic::riscv_vlsseg7:
3009 case Intrinsic::riscv_vlsseg8:
3010 case Intrinsic::riscv_vssseg2:
3011 case Intrinsic::riscv_vssseg3:
3012 case Intrinsic::riscv_vssseg4:
3013 case Intrinsic::riscv_vssseg5:
3014 case Intrinsic::riscv_vssseg6:
3015 case Intrinsic::riscv_vssseg7:
3016 case Intrinsic::riscv_vssseg8: {
3033 Ty = TarExtTy->getTypeParameter(0U);
3038 const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
3039 unsigned VLIndex = RVVIInfo->VLOperand;
3040 unsigned PtrOperandNo = VLIndex - 2 - HasMask;
3052 Alignment =
Align(1);
3059 unsigned SegNum = getSegNum(Inst, PtrOperandNo, IsWrite);
3062 unsigned ElemSize = Ty->getScalarSizeInBits();
3066 Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty,
3067 Alignment, Mask, EVL, Stride);
3070 case Intrinsic::riscv_vloxei_mask:
3071 case Intrinsic::riscv_vluxei_mask:
3072 case Intrinsic::riscv_vsoxei_mask:
3073 case Intrinsic::riscv_vsuxei_mask:
3074 case Intrinsic::riscv_vloxseg2_mask:
3075 case Intrinsic::riscv_vloxseg3_mask:
3076 case Intrinsic::riscv_vloxseg4_mask:
3077 case Intrinsic::riscv_vloxseg5_mask:
3078 case Intrinsic::riscv_vloxseg6_mask:
3079 case Intrinsic::riscv_vloxseg7_mask:
3080 case Intrinsic::riscv_vloxseg8_mask:
3081 case Intrinsic::riscv_vluxseg2_mask:
3082 case Intrinsic::riscv_vluxseg3_mask:
3083 case Intrinsic::riscv_vluxseg4_mask:
3084 case Intrinsic::riscv_vluxseg5_mask:
3085 case Intrinsic::riscv_vluxseg6_mask:
3086 case Intrinsic::riscv_vluxseg7_mask:
3087 case Intrinsic::riscv_vluxseg8_mask:
3088 case Intrinsic::riscv_vsoxseg2_mask:
3089 case Intrinsic::riscv_vsoxseg3_mask:
3090 case Intrinsic::riscv_vsoxseg4_mask:
3091 case Intrinsic::riscv_vsoxseg5_mask:
3092 case Intrinsic::riscv_vsoxseg6_mask:
3093 case Intrinsic::riscv_vsoxseg7_mask:
3094 case Intrinsic::riscv_vsoxseg8_mask:
3095 case Intrinsic::riscv_vsuxseg2_mask:
3096 case Intrinsic::riscv_vsuxseg3_mask:
3097 case Intrinsic::riscv_vsuxseg4_mask:
3098 case Intrinsic::riscv_vsuxseg5_mask:
3099 case Intrinsic::riscv_vsuxseg6_mask:
3100 case Intrinsic::riscv_vsuxseg7_mask:
3101 case Intrinsic::riscv_vsuxseg8_mask:
3104 case Intrinsic::riscv_vloxei:
3105 case Intrinsic::riscv_vluxei:
3106 case Intrinsic::riscv_vsoxei:
3107 case Intrinsic::riscv_vsuxei:
3108 case Intrinsic::riscv_vloxseg2:
3109 case Intrinsic::riscv_vloxseg3:
3110 case Intrinsic::riscv_vloxseg4:
3111 case Intrinsic::riscv_vloxseg5:
3112 case Intrinsic::riscv_vloxseg6:
3113 case Intrinsic::riscv_vloxseg7:
3114 case Intrinsic::riscv_vloxseg8:
3115 case Intrinsic::riscv_vluxseg2:
3116 case Intrinsic::riscv_vluxseg3:
3117 case Intrinsic::riscv_vluxseg4:
3118 case Intrinsic::riscv_vluxseg5:
3119 case Intrinsic::riscv_vluxseg6:
3120 case Intrinsic::riscv_vluxseg7:
3121 case Intrinsic::riscv_vluxseg8:
3122 case Intrinsic::riscv_vsoxseg2:
3123 case Intrinsic::riscv_vsoxseg3:
3124 case Intrinsic::riscv_vsoxseg4:
3125 case Intrinsic::riscv_vsoxseg5:
3126 case Intrinsic::riscv_vsoxseg6:
3127 case Intrinsic::riscv_vsoxseg7:
3128 case Intrinsic::riscv_vsoxseg8:
3129 case Intrinsic::riscv_vsuxseg2:
3130 case Intrinsic::riscv_vsuxseg3:
3131 case Intrinsic::riscv_vsuxseg4:
3132 case Intrinsic::riscv_vsuxseg5:
3133 case Intrinsic::riscv_vsuxseg6:
3134 case Intrinsic::riscv_vsuxseg7:
3135 case Intrinsic::riscv_vsuxseg8: {
3152 Ty = TarExtTy->getTypeParameter(0U);
3157 const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
3158 unsigned VLIndex = RVVIInfo->VLOperand;
3159 unsigned PtrOperandNo = VLIndex - 2 - HasMask;
3172 unsigned SegNum = getSegNum(Inst, PtrOperandNo, IsWrite);
3175 unsigned ElemSize = Ty->getScalarSizeInBits();
3180 Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty,
3181 Align(1), Mask, EVL,
3190 if (Ty->isVectorTy()) {
3193 if ((EltTy->
isHalfTy() && !ST->hasVInstructionsF16()) ||
3199 if (
Size.isScalable() && ST->hasVInstructions())
3202 if (ST->useRVVForFixedLengthVectors())
3222 return std::max<unsigned>(1U, RegWidth.
getFixedValue() / ElemWidth);
3230 return ST->enableUnalignedVectorMem();
3236 if (ST->hasVendorXCVmem() && !ST->is64Bit())
3258 Align Alignment)
const {
3260 if (!VTy || VTy->isScalableTy())
3268 if (VTy->getElementType()->isIntegerTy(8))
3269 if (VTy->getElementCount().getFixedValue() > 256)
3270 return VTy->getPrimitiveSizeInBits() / ST->getRealMinVLen() <
3271 ST->getMaxLMULForFixedLengthVectors();
3276 Align Alignment)
const {
3278 if (!VTy || VTy->isScalableTy())
3292 const Instruction &
I,
bool &AllowPromotionWithoutCommonHeader)
const {
3293 bool Considerable =
false;
3294 AllowPromotionWithoutCommonHeader =
false;
3297 Type *ConsideredSExtType =
3299 if (
I.getType() != ConsideredSExtType)
3303 for (
const User *U :
I.users()) {
3305 Considerable =
true;
3309 if (GEPInst->getNumOperands() > 2) {
3310 AllowPromotionWithoutCommonHeader =
true;
3315 return Considerable;
3320 case Instruction::Add:
3321 case Instruction::Sub:
3322 case Instruction::Mul:
3323 case Instruction::And:
3324 case Instruction::Or:
3325 case Instruction::Xor:
3326 case Instruction::FAdd:
3327 case Instruction::FSub:
3328 case Instruction::FMul:
3329 case Instruction::FDiv:
3330 case Instruction::ICmp:
3331 case Instruction::FCmp:
3333 case Instruction::Shl:
3334 case Instruction::LShr:
3335 case Instruction::AShr:
3336 case Instruction::UDiv:
3337 case Instruction::SDiv:
3338 case Instruction::URem:
3339 case Instruction::SRem:
3340 case Instruction::Select:
3341 return Operand == 1;
3348 if (!
I->getType()->isVectorTy() || !ST->hasVInstructions())
3358 switch (
II->getIntrinsicID()) {
3359 case Intrinsic::fma:
3360 case Intrinsic::vp_fma:
3361 case Intrinsic::fmuladd:
3362 case Intrinsic::vp_fmuladd:
3363 return Operand == 0 || Operand == 1;
3364 case Intrinsic::vp_shl:
3365 case Intrinsic::vp_lshr:
3366 case Intrinsic::vp_ashr:
3367 case Intrinsic::vp_udiv:
3368 case Intrinsic::vp_sdiv:
3369 case Intrinsic::vp_urem:
3370 case Intrinsic::vp_srem:
3371 case Intrinsic::ssub_sat:
3372 case Intrinsic::vp_ssub_sat:
3373 case Intrinsic::usub_sat:
3374 case Intrinsic::vp_usub_sat:
3375 case Intrinsic::vp_select:
3376 return Operand == 1;
3378 case Intrinsic::vp_add:
3379 case Intrinsic::vp_mul:
3380 case Intrinsic::vp_and:
3381 case Intrinsic::vp_or:
3382 case Intrinsic::vp_xor:
3383 case Intrinsic::vp_fadd:
3384 case Intrinsic::vp_fmul:
3385 case Intrinsic::vp_icmp:
3386 case Intrinsic::vp_fcmp:
3387 case Intrinsic::smin:
3388 case Intrinsic::vp_smin:
3389 case Intrinsic::umin:
3390 case Intrinsic::vp_umin:
3391 case Intrinsic::smax:
3392 case Intrinsic::vp_smax:
3393 case Intrinsic::umax:
3394 case Intrinsic::vp_umax:
3395 case Intrinsic::sadd_sat:
3396 case Intrinsic::vp_sadd_sat:
3397 case Intrinsic::uadd_sat:
3398 case Intrinsic::vp_uadd_sat:
3400 case Intrinsic::vp_sub:
3401 case Intrinsic::vp_fsub:
3402 case Intrinsic::vp_fdiv:
3403 return Operand == 0 || Operand == 1;
3416 if (
I->isBitwiseLogicOp()) {
3417 if (!
I->getType()->isVectorTy()) {
3418 if (ST->hasStdExtZbb() || ST->hasStdExtZbkb()) {
3419 for (
auto &
Op :
I->operands()) {
3427 }
else if (
I->getOpcode() == Instruction::And && ST->hasStdExtZvkb()) {
3428 for (
auto &
Op :
I->operands()) {
3440 Ops.push_back(&Not);
3441 Ops.push_back(&InsertElt);
3449 if (!
I->getType()->isVectorTy() || !ST->hasVInstructions())
3457 if (!ST->sinkSplatOperands())
3480 for (
Use &U :
Op->uses()) {
3487 Use *InsertEltUse = &
Op->getOperandUse(0);
3490 Ops.push_back(&InsertElt->getOperandUse(1));
3491 Ops.push_back(InsertEltUse);
3502 if (!ST->enableUnalignedScalarMem())
3505 if (!ST->hasStdExtZbb() && !ST->hasStdExtZbkb() && !IsZeroCmp)
3508 Options.AllowOverlappingLoads =
true;
3509 Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize);
3511 if (ST->is64Bit()) {
3512 Options.LoadSizes = {8, 4, 2, 1};
3513 Options.AllowedTailExpansions = {3, 5, 6};
3515 Options.LoadSizes = {4, 2, 1};
3516 Options.AllowedTailExpansions = {3};
3519 if (IsZeroCmp && ST->hasVInstructions()) {
3520 unsigned VLenB = ST->getRealMinVLen() / 8;
3523 unsigned MinSize = ST->getXLen() / 8 + 1;
3524 unsigned MaxSize = VLenB * ST->getMaxLMULForFixedLengthVectors();
3538 if (
I->getOpcode() == Instruction::Or &&
3543 if (
I->getOpcode() == Instruction::Add ||
3544 I->getOpcode() == Instruction::Sub)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file provides a helper that implements much of the TTI interface in terms of the target-independ...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool shouldSplit(Instruction *InsertPoint, DenseSet< Value * > &PrevConditionValues, DenseSet< Value * > &ConditionValues, DominatorTree &DT, DenseSet< Instruction * > &Unhoistables)
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.
static cl::opt< int > InstrCost("inline-instr-cost", cl::Hidden, cl::init(5), cl::desc("Cost of a single instruction when inlining"))
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static const Function * getCalledFunction(const Value *V)
MachineInstr unsigned OpIdx
uint64_t IntrinsicInst * II
static Type * getValueType(Value *V)
Returns the type of the given value/instruction V.
This file describes how to lower LLVM code to machine code.
Class for arbitrary precision integers.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
LLVM_ABI bool isStringAttribute() const
Return true if the attribute is a string (target-dependent) attribute.
LLVM_ABI StringRef getKindAsString() const
Return the attribute's kind as a string.
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 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 *CxtI=nullptr) const override
InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getGEPCost(Type *PointeeType, const Value *Ptr, ArrayRef< const Value * > Operands, Type *AccessType, TTI::TargetCostKind CostKind) 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 getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, ArrayRef< int > Mask, TTI::TargetCostKind CostKind, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) 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
std::optional< unsigned > getMaxVScale() 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 getIndexedVectorInstrCostFromEnd(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index) 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
bool isLegalAddImmediate(int64_t imm) const override
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
std::optional< unsigned > getVScaleForTuning() 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
unsigned getRegUsageForType(Type *Ty) 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
Value * getArgOperand(unsigned i) const
unsigned arg_size() const
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_SLT
signed less than
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
static bool isFPPredicate(Predicate P)
static bool isIntPredicate(Predicate P)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
A parsed version of the target data layout string in and methods for querying it.
Convenience struct for specifying and reasoning about fast-math flags.
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static FixedVectorType * getDoubleElementsVectorType(FixedVectorType *VTy)
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
static InstructionCost getInvalid(CostType Val=0)
CostType getValue() const
This function is intended to be used as sparingly as possible, since the class provides the full rang...
LLVM_ABI bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
const SmallVectorImpl< Type * > & getArgTypes() const
Type * getReturnType() const
const SmallVectorImpl< const Value * > & getArgs() const
Intrinsic::ID getID() const
bool isTypeBasedOnly() const
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
This is an important class for using LLVM in a threaded context.
Represents a single loop in the control flow graph.
static MVT getFloatingPointVT(unsigned BitWidth)
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
MVT changeVectorElementType(MVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
bool bitsLE(MVT VT) const
Return true if this has no more bits than VT.
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
MVT changeTypeToInteger()
Return the type converted to an equivalently sized integer or vector with integer element type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool bitsGT(MVT VT) const
Return true if this has more bits than VT.
bool isFixedLengthVector() const
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
MVT getVectorElementType() const
static MVT getIntegerVT(unsigned BitWidth)
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
Information for memory intrinsic cost model.
Align getAlignment() const
unsigned getAddressSpace() const
Type * getDataType() const
bool getVariableMask() const
Intrinsic::ID getID() const
const Instruction * getInst() const
unsigned getOpcode() const
Return the opcode for this Instruction or ConstantExpr.
InstructionCost getExtendedReductionCost(unsigned Opcode, bool IsUnsigned, Type *ResTy, VectorType *ValTy, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) 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 *CxtI=nullptr) const override
bool shouldCopyAttributeWhenOutliningFrom(const Function *Caller, const Attribute &Attr) const override
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
bool isLegalMaskedExpandLoad(Type *DataType, Align Alignment) const override
InstructionCost getStridedMemoryOpCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const
bool isLegalMaskedLoadStore(Type *DataType, Align Alignment) const
InstructionCost getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind) const override
unsigned getMinTripCountTailFoldingThreshold() const override
TTI::AddressingModeKind getPreferredAddressingMode(const Loop *L, ScalarEvolution *SE) const override
InstructionCost getAddressComputationCost(Type *PTy, ScalarEvolution *SE, const SCEV *Ptr, TTI::TargetCostKind CostKind) const override
InstructionCost getStoreImmCost(Type *VecTy, TTI::OperandValueInfo OpInfo, TTI::TargetCostKind CostKind) const
Return the cost of materializing an immediate for a value operand of a store instruction.
bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info) const override
InstructionCost getCostOfKeepingLiveOverCall(ArrayRef< Type * > Tys) const override
bool hasActiveVectorLength() const override
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) 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 getIndexedVectorInstrCostFromEnd(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index) const override
void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, TTI::UnrollingPreferences &UP, OptimizationRemarkEmitter *ORE) const override
InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind, Instruction *Inst=nullptr) const override
InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF, TTI::TargetCostKind CostKind) const override
Try to calculate op costs for min/max reduction operations.
bool canSplatOperand(Instruction *I, int Operand) const
Return true if the (vector) instruction I will be lowered to an instruction with a scalar splat opera...
bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1, const TargetTransformInfo::LSRCost &C2) const override
bool isLegalStridedLoadStore(Type *DataType, Align Alignment) const override
unsigned getRegUsageForType(Type *Ty) 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
bool isLegalMaskedScatter(Type *DataType, Align Alignment) const override
bool isLegalMaskedCompressStore(Type *DataTy, Align Alignment) const override
InstructionCost getGatherScatterOpCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const
InstructionCost getPartialReductionCost(unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType, ElementCount VF, TTI::PartialReductionExtendKind OpAExtend, TTI::PartialReductionExtendKind OpBExtend, std::optional< unsigned > BinOp, TTI::TargetCostKind CostKind, std::optional< FastMathFlags > FMF) const override
bool shouldTreatInstructionLikeSelect(const Instruction *I) const override
InstructionCost getExpandCompressMemoryOpCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const
bool preferAlternateOpcodeVectorization() 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...
std::optional< unsigned > getMaxVScale() const override
bool shouldExpandReduction(const IntrinsicInst *II) const override
std::optional< unsigned > getVScaleForTuning() const override
InstructionCost getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const override
Get memory intrinsic cost based on arguments.
bool isLegalMaskedGather(Type *DataType, Align Alignment) const override
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, ArrayRef< int > Mask, TTI::TargetCostKind CostKind, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) const override
InstructionCost getPointersChainCost(ArrayRef< const Value * > Ptrs, const Value *Base, const TTI::PointersChainInfo &Info, Type *AccessTy, TTI::TargetCostKind CostKind) const override
TTI::MemCmpExpansionOptions enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const override
InstructionCost getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
Estimate the overhead of scalarizing an instruction.
InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpdInfo={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const override
Get intrinsic cost based on arguments.
InstructionCost getMaskedMemoryOpCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const
InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override
void getPeelingPreferences(Loop *L, ScalarEvolution &SE, TTI::PeelingPreferences &PP) const override
bool shouldConsiderAddressTypePromotion(const Instruction &I, bool &AllowPromotionWithoutCommonHeader) const override
See if I should be considered for address type promotion.
InstructionCost getIntImmCost(const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind) const override
TargetTransformInfo::PopcntSupportKind getPopcntSupport(unsigned TyWidth) const override
static MVT getM1VT(MVT VT)
Given a vector (either fixed or scalable), return the scalable vector corresponding to a vector regis...
InstructionCost getVRGatherVVCost(MVT VT) const
Return the cost of a vrgather.vv instruction for the type VT.
InstructionCost getVRGatherVICost(MVT VT) const
Return the cost of a vrgather.vi (or vx) instruction for the type VT.
static unsigned computeVLMAX(unsigned VectorBits, unsigned EltSize, unsigned MinSize)
InstructionCost getLMULCost(MVT VT) const
Return the cost of LMUL for linear operations.
InstructionCost getVSlideVICost(MVT VT) const
Return the cost of a vslidedown.vi or vslideup.vi instruction for the type VT.
InstructionCost getVSlideVXCost(MVT VT) const
Return the cost of a vslidedown.vx or vslideup.vx instruction for the type VT.
static RISCVVType::VLMUL getLMUL(MVT VT)
This class represents an analyzed expression in the program.
static LLVM_ABI ScalableVectorType * get(Type *ElementType, unsigned MinNumElts)
The main scalar evolution driver.
static LLVM_ABI bool isIdentityMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses elements from exactly one source vector without lane crossin...
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.
Implements a dense probed hash-table based set with some number of buckets stored inline.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
static constexpr TypeSize getScalable(ScalarTy MinimumSize)
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
bool isVectorTy() const
True if this is an instance of VectorType.
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
bool isBFloatTy() const
Return true if this is 'bfloat', a 16-bit bfloat type.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
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.
LLVM_ABI Type * getWithNewType(Type *EltTy) const
Given vector type, change the element type, whilst keeping the old number of elements.
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.
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
bool isVoidTy() const
Return true if this is 'void'.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
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...
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
std::pair< iterator, bool > insert(const ValueT &V)
constexpr bool isKnownMultipleOf(ScalarTy RHS) const
This function tells the caller whether the element count is known at compile time to be a multiple of...
constexpr ScalarTy getFixedValue() const
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const
We do not provide the '/' operator here because division for polynomial types does not work in the sa...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
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.
@ SIGN_EXTEND
Conversion operators.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ 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< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
bool match(Val *V, const Pattern &P)
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
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.
int getIntMatCost(const APInt &Val, unsigned Size, const MCSubtargetInfo &STI, bool CompressionCost, bool FreeZeroes)
static constexpr unsigned RVVBitsPerBlock
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
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.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
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.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
LLVM_ABI llvm::SmallVector< int, 16 > createStrideMask(unsigned Start, unsigned Stride, unsigned VF)
Create a stride shuffle mask.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
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...
constexpr int PoisonMaskElem
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
LLVM_ABI bool isMaskedSlidePair(ArrayRef< int > Mask, int NumElts, std::array< std::pair< int, int >, 2 > &SrcInfo)
Does this shuffle mask represent either one slide shuffle or a pair of two slide shuffles,...
LLVM_ABI llvm::SmallVector< int, 16 > createInterleaveMask(unsigned VF, unsigned NumVecs)
Create an interleave shuffle mask.
DWARFExpression::Operation Op
CostTblEntryT< unsigned > CostTblEntry
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
bool equal(L &&LRange, R &&RRange)
Wrapper function around std::equal to detect if pair-wise elements between two ranges are the same.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
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.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Information about a load/store intrinsic defined by the target.