18#include "llvm/IR/IntrinsicsRISCV.h"
26#define DEBUG_TYPE "riscvtti"
29 "riscv-v-register-bit-width-lmul",
31 "The LMUL to use for getRegisterBitWidth queries. Affects LMUL used "
32 "by autovectorized code. Fractional LMULs are not supported."),
38 "Overrides result used for getMaximumVF query which is used "
39 "exclusively by SLP vectorizer."),
44 cl::desc(
"Set the lower bound of a trip count to decide on "
45 "vectorization while tail-folding."),
57 size_t NumInstr = OpCodes.size();
62 return LMULCost * NumInstr;
64 for (
auto Op : OpCodes) {
66 case RISCV::VRGATHER_VI:
69 case RISCV::VRGATHER_VV:
72 case RISCV::VSLIDEUP_VI:
73 case RISCV::VSLIDEDOWN_VI:
76 case RISCV::VSLIDEUP_VX:
77 case RISCV::VSLIDEDOWN_VX:
80 case RISCV::VREDMAX_VS:
81 case RISCV::VREDMIN_VS:
82 case RISCV::VREDMAXU_VS:
83 case RISCV::VREDMINU_VS:
84 case RISCV::VREDSUM_VS:
85 case RISCV::VREDAND_VS:
86 case RISCV::VREDOR_VS:
87 case RISCV::VREDXOR_VS:
88 case RISCV::VFREDMAX_VS:
89 case RISCV::VFREDMIN_VS:
90 case RISCV::VFREDUSUM_VS: {
97 case RISCV::VFREDOSUM_VS: {
105 case RISCV::VFMV_F_S:
110 case RISCV::VFMV_S_F:
112 case RISCV::VMXOR_MM:
113 case RISCV::VMAND_MM:
114 case RISCV::VMANDN_MM:
115 case RISCV::VMNAND_MM:
117 case RISCV::VFIRST_M:
136 assert(Ty->isIntegerTy() &&
137 "getIntImmCost can only estimate cost of materialising integers");
160 if (!BO || !BO->hasOneUse())
163 if (BO->getOpcode() != Instruction::Shl)
174 if (ShAmt == Trailing)
191 if (!Cmp || !Cmp->isEquality())
207 if ((CmpC & Mask) != CmpC)
214 return NewCmpC >= -2048 && NewCmpC <= 2048;
221 assert(Ty->isIntegerTy() &&
222 "getIntImmCost can only estimate cost of materialising integers");
230 bool Takes12BitImm =
false;
231 unsigned ImmArgIdx = ~0U;
234 case Instruction::GetElementPtr:
239 case Instruction::Store: {
244 if (Idx == 1 || !Inst)
249 if (!getTLI()->allowsMemoryAccessForAlignment(
257 case Instruction::Load:
260 case Instruction::And:
262 if (Imm == UINT64_C(0xffff) && ST->hasStdExtZbb())
265 if (Imm == UINT64_C(0xffffffff) &&
266 ((ST->hasStdExtZba() && ST->isRV64()) || ST->isRV32()))
269 if (ST->hasStdExtZbs() && (~Imm).isPowerOf2())
271 if (Inst && Idx == 1 && Imm.getBitWidth() <= ST->getXLen() &&
274 if (Inst && Idx == 1 && Imm.getBitWidth() == 64 &&
277 Takes12BitImm =
true;
279 case Instruction::Add:
280 Takes12BitImm =
true;
282 case Instruction::Or:
283 case Instruction::Xor:
285 if (ST->hasStdExtZbs() && Imm.isPowerOf2())
287 Takes12BitImm =
true;
289 case Instruction::Mul:
291 if (Imm.isPowerOf2() || Imm.isNegatedPowerOf2())
294 if ((Imm + 1).isPowerOf2() || (Imm - 1).isPowerOf2())
297 Takes12BitImm =
true;
299 case Instruction::Sub:
300 case Instruction::Shl:
301 case Instruction::LShr:
302 case Instruction::AShr:
303 Takes12BitImm =
true;
314 if (Imm.getSignificantBits() <= 64 &&
337 return ST->hasVInstructions();
347 unsigned Opcode,
Type *InputTypeA,
Type *InputTypeB,
Type *AccumType,
351 if (Opcode == Instruction::FAdd)
356 if (!ST->hasStdExtZvdot4a8i() || ST->getELen() < 64 ||
357 Opcode != Instruction::Add || !BinOp || *BinOp != Instruction::Mul ||
358 InputTypeA != InputTypeB || !InputTypeA->
isIntegerTy(8) ||
366 getRISCVInstructionCost(RISCV::VDOT4A_VV, LT.second,
CostKind);
373 switch (
II->getIntrinsicID()) {
377 case Intrinsic::vector_reduce_mul:
378 case Intrinsic::vector_reduce_fmul:
384 if (ST->hasVInstructions())
390 if (ST->hasVInstructions())
391 if (
unsigned MinVLen = ST->getRealMinVLen();
406 ST->useRVVForFixedLengthVectors() ? LMUL * ST->getRealMinVLen() : 0);
409 (ST->hasVInstructions() &&
432 return (ST->hasAUIPCADDIFusion() && ST->hasLUIADDIFusion()) ? 1 : 2;
438RISCVTTIImpl::getConstantPoolLoadCost(
Type *Ty,
443 return getStaticDataAddrGenerationCost(
CostKind) +
449 unsigned Size = Mask.size();
452 for (
unsigned I = 0;
I !=
Size; ++
I) {
453 if (
static_cast<unsigned>(Mask[
I]) ==
I)
459 for (
unsigned J =
I + 1; J !=
Size; ++J)
461 if (
static_cast<unsigned>(Mask[J]) != J %
I)
489 "Expected fixed vector type and non-empty mask");
492 unsigned NumOfDests =
divideCeil(Mask.size(), LegalNumElts);
496 if (NumOfDests <= 1 ||
498 Tp->getElementType()->getPrimitiveSizeInBits() ||
499 LegalNumElts >= Tp->getElementCount().getFixedValue())
502 unsigned VecTySize =
TTI.getDataLayout().getTypeStoreSize(Tp);
505 unsigned NumOfSrcs =
divideCeil(VecTySize, LegalVTSize);
509 unsigned NormalizedVF = LegalNumElts * std::max(NumOfSrcs, NumOfDests);
510 unsigned NumOfSrcRegs = NormalizedVF / LegalNumElts;
511 unsigned NumOfDestRegs = NormalizedVF / LegalNumElts;
513 assert(NormalizedVF >= Mask.size() &&
514 "Normalized mask expected to be not shorter than original mask.");
519 NormalizedMask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, []() {},
520 [&](
ArrayRef<int> RegMask,
unsigned SrcReg,
unsigned DestReg) {
523 if (!ReusedSingleSrcShuffles.
insert(std::make_pair(RegMask, SrcReg))
526 Cost +=
TTI.getShuffleCost(
529 SingleOpTy, RegMask,
CostKind, 0,
nullptr);
531 [&](
ArrayRef<int> RegMask,
unsigned Idx1,
unsigned Idx2,
bool NewReg) {
532 Cost +=
TTI.getShuffleCost(
535 SingleOpTy, RegMask,
CostKind, 0,
nullptr);
558 if (!VLen || Mask.empty())
562 LegalVT =
TTI.getTypeLegalizationCost(
568 if (NumOfDests <= 1 ||
570 Tp->getElementType()->getPrimitiveSizeInBits() ||
574 unsigned VecTySize =
TTI.getDataLayout().getTypeStoreSize(Tp);
577 unsigned NumOfSrcs =
divideCeil(VecTySize, LegalVTSize);
583 unsigned NormalizedVF =
588 assert(NormalizedVF >= Mask.size() &&
589 "Normalized mask expected to be not shorter than original mask.");
595 NormalizedMask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, []() {},
596 [&](
ArrayRef<int> RegMask,
unsigned SrcReg,
unsigned DestReg) {
599 if (!ReusedSingleSrcShuffles.
insert(std::make_pair(RegMask, SrcReg))
604 SingleOpTy, RegMask,
CostKind, 0,
nullptr);
606 [&](
ArrayRef<int> RegMask,
unsigned Idx1,
unsigned Idx2,
bool NewReg) {
608 SingleOpTy, RegMask,
CostKind, 0,
nullptr);
615 if ((NumOfDestRegs > 2 && NumShuffles <=
static_cast<int>(NumOfDestRegs)) ||
616 (NumOfDestRegs <= 2 && NumShuffles < 4))
631 if (!
LT.second.isFixedLengthVector())
639 auto GetSlideOpcode = [&](
int SlideAmt) {
641 bool IsVI =
isUInt<5>(std::abs(SlideAmt));
643 return IsVI ? RISCV::VSLIDEDOWN_VI : RISCV::VSLIDEDOWN_VX;
644 return IsVI ? RISCV::VSLIDEUP_VI : RISCV::VSLIDEUP_VX;
647 std::array<std::pair<int, int>, 2> SrcInfo;
651 if (SrcInfo[1].second == 0)
655 if (SrcInfo[0].second != 0) {
656 unsigned Opcode = GetSlideOpcode(SrcInfo[0].second);
657 FirstSlideCost = getRISCVInstructionCost(Opcode,
LT.second,
CostKind);
660 if (SrcInfo[1].first == -1)
661 return FirstSlideCost;
664 if (SrcInfo[1].second != 0) {
665 unsigned Opcode = GetSlideOpcode(SrcInfo[1].second);
666 SecondSlideCost = getRISCVInstructionCost(Opcode,
LT.second,
CostKind);
669 getRISCVInstructionCost(RISCV::VMERGE_VVM,
LT.second,
CostKind);
676 return FirstSlideCost + SecondSlideCost + MaskCost;
687 "Expected the Mask to match the return size if given");
689 "Expected the same scalar types");
705 FVTp && ST->hasVInstructions() && LT.second.isFixedLengthVector()) {
707 *
this, LT.second, ST->getRealVLen(),
709 if (VRegSplittingCost.
isValid())
710 return VRegSplittingCost;
715 if (Mask.size() >= 2) {
716 MVT EltTp = LT.second.getVectorElementType();
727 return 2 * LT.first * TLI->getLMULCost(LT.second);
729 if (Mask[0] == 0 || Mask[0] == 1) {
733 if (
equal(DeinterleaveMask, Mask))
734 return LT.first * getRISCVInstructionCost(RISCV::VNSRL_WI,
739 if (LT.second.getScalarSizeInBits() != 1 &&
742 unsigned NumSlides =
Log2_32(Mask.size() / SubVectorSize);
744 for (
unsigned I = 0;
I != NumSlides; ++
I) {
745 unsigned InsertIndex = SubVectorSize * (1 <<
I);
750 std::pair<InstructionCost, MVT> DestLT =
755 Cost += DestLT.first * TLI->getLMULCost(DestLT.second);
769 if (LT.first == 1 && (LT.second.getScalarSizeInBits() != 8 ||
770 LT.second.getVectorNumElements() <= 256)) {
775 getRISCVInstructionCost(RISCV::VRGATHER_VV, LT.second,
CostKind);
789 if (LT.first == 1 && (LT.second.getScalarSizeInBits() != 8 ||
790 LT.second.getVectorNumElements() <= 256)) {
791 auto &
C = SrcTy->getContext();
792 auto EC = SrcTy->getElementCount();
797 return 2 * IndexCost +
798 getRISCVInstructionCost({RISCV::VRGATHER_VV, RISCV::VRGATHER_VV},
817 if (!Mask.empty() && LT.first.isValid() && LT.first != 1 &&
845 SubLT.second.isValid() && SubLT.second.isFixedLengthVector()) {
846 if (std::optional<unsigned> VLen = ST->getRealVLen();
847 VLen && SubLT.second.getScalarSizeInBits() * Index % *VLen == 0 &&
848 SubLT.second.getSizeInBits() <= *VLen)
856 getRISCVInstructionCost(RISCV::VSLIDEDOWN_VI, LT.second,
CostKind);
863 getRISCVInstructionCost(RISCV::VSLIDEUP_VI, LT.second,
CostKind);
875 (1 + getRISCVInstructionCost({RISCV::VMV_S_X, RISCV::VMERGE_VVM},
882 if (IsLoad && LT.second.isVector() &&
884 LT.second.getVectorElementCount()))
888 Instruction::InsertElement);
889 if (LT.second.getScalarSizeInBits() == 1) {
897 (1 + getRISCVInstructionCost({RISCV::VMV_V_X, RISCV::VMSNE_VI},
910 (1 + getRISCVInstructionCost({RISCV::VMV_V_I, RISCV::VMERGE_VIM,
911 RISCV::VMV_X_S, RISCV::VMV_V_X,
920 getRISCVInstructionCost(RISCV::VMV_V_X, LT.second,
CostKind);
926 getRISCVInstructionCost(RISCV::VRGATHER_VI, LT.second,
CostKind);
932 unsigned Opcodes[2] = {RISCV::VSLIDEDOWN_VX, RISCV::VSLIDEUP_VX};
933 if (Index >= 0 && Index < 32)
934 Opcodes[0] = RISCV::VSLIDEDOWN_VI;
935 else if (Index < 0 && Index > -32)
936 Opcodes[1] = RISCV::VSLIDEUP_VI;
937 return LT.first * getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
941 if (!LT.second.isVector())
947 if (SrcTy->getElementType()->isIntegerTy(1)) {
959 MVT ContainerVT = LT.second;
960 if (LT.second.isFixedLengthVector())
961 ContainerVT = TLI->getContainerForFixedLengthVector(LT.second);
963 if (ContainerVT.
bitsLE(M1VT)) {
973 if (LT.second.isFixedLengthVector())
975 LenCost =
isInt<5>(LT.second.getVectorNumElements() - 1) ? 0 : 1;
976 unsigned Opcodes[] = {RISCV::VID_V, RISCV::VRSUB_VX, RISCV::VRGATHER_VV};
977 if (LT.second.isFixedLengthVector() &&
978 isInt<5>(LT.second.getVectorNumElements() - 1))
979 Opcodes[1] = RISCV::VRSUB_VI;
981 getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
982 return LT.first * (LenCost + GatherCost);
989 unsigned M1Opcodes[] = {RISCV::VID_V, RISCV::VRSUB_VX};
991 getRISCVInstructionCost(M1Opcodes, M1VT,
CostKind) + 3;
995 getRISCVInstructionCost({RISCV::VRGATHER_VV}, M1VT,
CostKind) * Ratio;
997 getRISCVInstructionCost({RISCV::VSLIDEDOWN_VX}, LT.second,
CostKind);
998 return FixedCost + LT.first * (GatherCost + SlideCost);
1032 Ty, DemandedElts, Insert, Extract,
CostKind);
1034 if (Insert && !Extract && LT.first.isValid() && LT.second.isVector()) {
1035 if (Ty->getScalarSizeInBits() == 1) {
1045 assert(LT.second.isFixedLengthVector());
1046 MVT ContainerVT = TLI->getContainerForFixedLengthVector(LT.second);
1050 getRISCVInstructionCost(RISCV::VSLIDE1DOWN_VX, LT.second,
CostKind);
1063 switch (MICA.
getID()) {
1064 case Intrinsic::vp_load_ff: {
1065 EVT DataTypeVT = TLI->getValueType(
DL, DataTy);
1066 if (!TLI->isLegalFirstFaultLoad(DataTypeVT, Alignment))
1073 case Intrinsic::experimental_vp_strided_load:
1074 case Intrinsic::experimental_vp_strided_store:
1076 case Intrinsic::masked_compressstore:
1077 case Intrinsic::masked_expandload:
1079 case Intrinsic::vp_scatter:
1080 case Intrinsic::vp_gather:
1081 case Intrinsic::masked_scatter:
1082 case Intrinsic::masked_gather:
1084 case Intrinsic::vp_load:
1085 case Intrinsic::vp_store:
1086 case Intrinsic::masked_load:
1087 case Intrinsic::masked_store:
1096 unsigned Opcode = MICA.
getID() == Intrinsic::masked_load ? Instruction::Load
1097 : Instruction::Store;
1112 bool UseMaskForCond,
bool UseMaskForGaps)
const {
1118 if (!UseMaskForGaps && Factor <= TLI->getMaxSupportedInterleaveFactor()) {
1122 if (LT.second.isVector()) {
1128 VTy->getElementCount().divideCoefficientBy(Factor));
1129 if (VTy->getElementCount().isKnownMultipleOf(Factor) &&
1130 TLI->isLegalInterleavedAccessType(SubVecTy, Factor, Alignment,
1135 if (ST->hasOptimizedSegmentLoadStore(Factor)) {
1138 MVT SubVecVT = getTLI()->getValueType(
DL, SubVecTy).getSimpleVT();
1139 Cost += Factor * TLI->getLMULCost(SubVecVT);
1140 return LT.first *
Cost;
1145 unsigned NumLoads = getEstimatedVLFor(VTy);
1161 if (UseMaskForGaps) {
1164 "Indices should not contain duplicate elements");
1165 unsigned NumOfFields = Indices.
size();
1166 bool IsTailGapOnly = NumOfFields > 1 && (NumOfFields == Indices.
back() + 1);
1167 if (IsTailGapOnly &&
1168 NumOfFields <= TLI->getMaxSupportedInterleaveFactor()) {
1170 if (LT.second.isVector() &&
1171 FVTy->getElementCount().isKnownMultipleOf(Factor)) {
1173 FVTy->getElementType(),
1174 FVTy->getElementCount().divideCoefficientBy(Factor));
1175 if (TLI->isLegalInterleavedAccessType(SubVecTy, NumOfFields, Alignment,
1178 unsigned NumAccesses = getEstimatedVLFor(FVTy);
1187 unsigned VF = FVTy->getNumElements() / Factor;
1194 if (Opcode == Instruction::Load) {
1196 for (
unsigned Index : Indices) {
1200 Mask.resize(VF * Factor, -1);
1204 Cost += ShuffleCost;
1222 UseMaskForCond, UseMaskForGaps);
1224 assert(Opcode == Instruction::Store &&
"Opcode must be a store");
1231 return MemCost + ShuffleCost;
1238 bool IsLoad = MICA.
getID() == Intrinsic::masked_gather ||
1239 MICA.
getID() == Intrinsic::vp_gather;
1240 unsigned Opcode = IsLoad ? Instruction::Load : Instruction::Store;
1246 if ((Opcode == Instruction::Load &&
1248 (Opcode == Instruction::Store &&
1256 unsigned NumLoads = getEstimatedVLFor(&VTy);
1263 unsigned Opcode = MICA.
getID() == Intrinsic::masked_expandload
1265 : Instruction::Store;
1269 bool IsLegal = (Opcode == Instruction::Store &&
1271 (Opcode == Instruction::Load &&
1295 if (Opcode == Instruction::Store)
1296 Opcodes.
append({RISCV::VCOMPRESS_VM});
1298 Opcodes.
append({RISCV::VSETIVLI, RISCV::VIOTA_M, RISCV::VRGATHER_VV});
1300 LT.first * getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
1319 unsigned NumLoads = getEstimatedVLFor(&VTy);
1330 for (
auto *Ty : Tys) {
1331 if (!Ty->isVectorTy())
1345 {Intrinsic::floor, MVT::f32, 9},
1346 {Intrinsic::floor, MVT::f64, 9},
1347 {Intrinsic::ceil, MVT::f32, 9},
1348 {Intrinsic::ceil, MVT::f64, 9},
1349 {Intrinsic::trunc, MVT::f32, 7},
1350 {Intrinsic::trunc, MVT::f64, 7},
1351 {Intrinsic::round, MVT::f32, 9},
1352 {Intrinsic::round, MVT::f64, 9},
1353 {Intrinsic::roundeven, MVT::f32, 9},
1354 {Intrinsic::roundeven, MVT::f64, 9},
1355 {Intrinsic::rint, MVT::f32, 7},
1356 {Intrinsic::rint, MVT::f64, 7},
1357 {Intrinsic::nearbyint, MVT::f32, 9},
1358 {Intrinsic::nearbyint, MVT::f64, 9},
1359 {Intrinsic::bswap, MVT::i16, 3},
1360 {Intrinsic::bswap, MVT::i32, 12},
1361 {Intrinsic::bswap, MVT::i64, 31},
1362 {Intrinsic::vp_bswap, MVT::i16, 3},
1363 {Intrinsic::vp_bswap, MVT::i32, 12},
1364 {Intrinsic::vp_bswap, MVT::i64, 31},
1365 {Intrinsic::vp_fshl, MVT::i8, 7},
1366 {Intrinsic::vp_fshl, MVT::i16, 7},
1367 {Intrinsic::vp_fshl, MVT::i32, 7},
1368 {Intrinsic::vp_fshl, MVT::i64, 7},
1369 {Intrinsic::vp_fshr, MVT::i8, 7},
1370 {Intrinsic::vp_fshr, MVT::i16, 7},
1371 {Intrinsic::vp_fshr, MVT::i32, 7},
1372 {Intrinsic::vp_fshr, MVT::i64, 7},
1373 {Intrinsic::bitreverse, MVT::i8, 17},
1374 {Intrinsic::bitreverse, MVT::i16, 24},
1375 {Intrinsic::bitreverse, MVT::i32, 33},
1376 {Intrinsic::bitreverse, MVT::i64, 52},
1377 {Intrinsic::vp_bitreverse, MVT::i8, 17},
1378 {Intrinsic::vp_bitreverse, MVT::i16, 24},
1379 {Intrinsic::vp_bitreverse, MVT::i32, 33},
1380 {Intrinsic::vp_bitreverse, MVT::i64, 52},
1381 {Intrinsic::ctpop, MVT::i8, 12},
1382 {Intrinsic::ctpop, MVT::i16, 19},
1383 {Intrinsic::ctpop, MVT::i32, 20},
1384 {Intrinsic::ctpop, MVT::i64, 21},
1385 {Intrinsic::ctlz, MVT::i8, 19},
1386 {Intrinsic::ctlz, MVT::i16, 28},
1387 {Intrinsic::ctlz, MVT::i32, 31},
1388 {Intrinsic::ctlz, MVT::i64, 35},
1389 {Intrinsic::cttz, MVT::i8, 16},
1390 {Intrinsic::cttz, MVT::i16, 23},
1391 {Intrinsic::cttz, MVT::i32, 24},
1392 {Intrinsic::cttz, MVT::i64, 25},
1393 {Intrinsic::vp_ctpop, MVT::i8, 12},
1394 {Intrinsic::vp_ctpop, MVT::i16, 19},
1395 {Intrinsic::vp_ctpop, MVT::i32, 20},
1396 {Intrinsic::vp_ctpop, MVT::i64, 21},
1397 {Intrinsic::vp_ctlz, MVT::i8, 19},
1398 {Intrinsic::vp_ctlz, MVT::i16, 28},
1399 {Intrinsic::vp_ctlz, MVT::i32, 31},
1400 {Intrinsic::vp_ctlz, MVT::i64, 35},
1401 {Intrinsic::vp_cttz, MVT::i8, 16},
1402 {Intrinsic::vp_cttz, MVT::i16, 23},
1403 {Intrinsic::vp_cttz, MVT::i32, 24},
1404 {Intrinsic::vp_cttz, MVT::i64, 25},
1411 switch (ICA.
getID()) {
1412 case Intrinsic::lrint:
1413 case Intrinsic::llrint:
1414 case Intrinsic::lround:
1415 case Intrinsic::llround: {
1419 if (ST->hasVInstructions() && LT.second.isVector()) {
1421 unsigned SrcEltSz =
DL.getTypeSizeInBits(SrcTy->getScalarType());
1422 unsigned DstEltSz =
DL.getTypeSizeInBits(RetTy->getScalarType());
1423 if (LT.second.getVectorElementType() == MVT::bf16) {
1424 if (!ST->hasVInstructionsBF16Minimal())
1427 Ops = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFCVT_X_F_V};
1429 Ops = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFWCVT_X_F_V};
1430 }
else if (LT.second.getVectorElementType() == MVT::f16 &&
1431 !ST->hasVInstructionsF16()) {
1432 if (!ST->hasVInstructionsF16Minimal())
1435 Ops = {RISCV::VFWCVT_F_F_V, RISCV::VFCVT_X_F_V};
1437 Ops = {RISCV::VFWCVT_F_F_V, RISCV::VFWCVT_X_F_V};
1439 }
else if (SrcEltSz > DstEltSz) {
1440 Ops = {RISCV::VFNCVT_X_F_W};
1441 }
else if (SrcEltSz < DstEltSz) {
1442 Ops = {RISCV::VFWCVT_X_F_V};
1444 Ops = {RISCV::VFCVT_X_F_V};
1449 if (SrcEltSz > DstEltSz)
1450 return SrcLT.first *
1451 getRISCVInstructionCost(
Ops, SrcLT.second,
CostKind);
1452 return LT.first * getRISCVInstructionCost(
Ops, LT.second,
CostKind);
1456 case Intrinsic::ceil:
1457 case Intrinsic::floor:
1458 case Intrinsic::trunc:
1459 case Intrinsic::rint:
1460 case Intrinsic::round:
1461 case Intrinsic::roundeven: {
1464 if (!LT.second.isVector() && TLI->isOperationCustom(
ISD::FCEIL, LT.second))
1465 return LT.first * 8;
1468 case Intrinsic::umin:
1469 case Intrinsic::umax:
1470 case Intrinsic::smin:
1471 case Intrinsic::smax: {
1473 if (LT.second.isScalarInteger() && ST->hasStdExtZbb())
1476 if (ST->hasVInstructions() && LT.second.isVector()) {
1478 switch (ICA.
getID()) {
1479 case Intrinsic::umin:
1480 Op = RISCV::VMINU_VV;
1482 case Intrinsic::umax:
1483 Op = RISCV::VMAXU_VV;
1485 case Intrinsic::smin:
1486 Op = RISCV::VMIN_VV;
1488 case Intrinsic::smax:
1489 Op = RISCV::VMAX_VV;
1492 return LT.first * getRISCVInstructionCost(
Op, LT.second,
CostKind);
1496 case Intrinsic::sadd_sat:
1497 case Intrinsic::ssub_sat:
1498 case Intrinsic::uadd_sat:
1499 case Intrinsic::usub_sat: {
1501 if (ST->hasVInstructions() && LT.second.isVector()) {
1503 switch (ICA.
getID()) {
1504 case Intrinsic::sadd_sat:
1505 Op = RISCV::VSADD_VV;
1507 case Intrinsic::ssub_sat:
1508 Op = RISCV::VSSUB_VV;
1510 case Intrinsic::uadd_sat:
1511 Op = RISCV::VSADDU_VV;
1513 case Intrinsic::usub_sat:
1514 Op = RISCV::VSSUBU_VV;
1517 return LT.first * getRISCVInstructionCost(
Op, LT.second,
CostKind);
1521 case Intrinsic::fma:
1522 case Intrinsic::fmuladd: {
1525 if (ST->hasVInstructions() && LT.second.isVector())
1527 getRISCVInstructionCost(RISCV::VFMADD_VV, LT.second,
CostKind);
1530 case Intrinsic::fabs: {
1532 if (ST->hasVInstructions() && LT.second.isVector()) {
1538 if (LT.second.getVectorElementType() == MVT::bf16 ||
1539 (LT.second.getVectorElementType() == MVT::f16 &&
1540 !ST->hasVInstructionsF16()))
1541 return LT.first * getRISCVInstructionCost(RISCV::VAND_VX, LT.second,
1546 getRISCVInstructionCost(RISCV::VFSGNJX_VV, LT.second,
CostKind);
1550 case Intrinsic::sqrt: {
1552 if (ST->hasVInstructions() && LT.second.isVector()) {
1555 MVT ConvType = LT.second;
1556 MVT FsqrtType = LT.second;
1559 if (LT.second.getVectorElementType() == MVT::bf16) {
1560 if (LT.second == MVT::nxv32bf16) {
1561 ConvOp = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFWCVTBF16_F_F_V,
1562 RISCV::VFNCVTBF16_F_F_W, RISCV::VFNCVTBF16_F_F_W};
1563 FsqrtOp = {RISCV::VFSQRT_V, RISCV::VFSQRT_V};
1564 ConvType = MVT::nxv16f16;
1565 FsqrtType = MVT::nxv16f32;
1567 ConvOp = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFNCVTBF16_F_F_W};
1568 FsqrtOp = {RISCV::VFSQRT_V};
1569 FsqrtType = TLI->getTypeToPromoteTo(
ISD::FSQRT, FsqrtType);
1571 }
else if (LT.second.getVectorElementType() == MVT::f16 &&
1572 !ST->hasVInstructionsF16()) {
1573 if (LT.second == MVT::nxv32f16) {
1574 ConvOp = {RISCV::VFWCVT_F_F_V, RISCV::VFWCVT_F_F_V,
1575 RISCV::VFNCVT_F_F_W, RISCV::VFNCVT_F_F_W};
1576 FsqrtOp = {RISCV::VFSQRT_V, RISCV::VFSQRT_V};
1577 ConvType = MVT::nxv16f16;
1578 FsqrtType = MVT::nxv16f32;
1580 ConvOp = {RISCV::VFWCVT_F_F_V, RISCV::VFNCVT_F_F_W};
1581 FsqrtOp = {RISCV::VFSQRT_V};
1582 FsqrtType = TLI->getTypeToPromoteTo(
ISD::FSQRT, FsqrtType);
1585 FsqrtOp = {RISCV::VFSQRT_V};
1588 return LT.first * (getRISCVInstructionCost(FsqrtOp, FsqrtType,
CostKind) +
1589 getRISCVInstructionCost(ConvOp, ConvType,
CostKind));
1593 case Intrinsic::cttz:
1594 case Intrinsic::ctlz:
1595 case Intrinsic::ctpop: {
1597 if (ST->hasStdExtZvbb() && LT.second.isVector()) {
1599 switch (ICA.
getID()) {
1600 case Intrinsic::cttz:
1603 case Intrinsic::ctlz:
1606 case Intrinsic::ctpop:
1607 Op = RISCV::VCPOP_V;
1610 return LT.first * getRISCVInstructionCost(
Op, LT.second,
CostKind);
1614 case Intrinsic::abs: {
1616 if (ST->hasVInstructions() && LT.second.isVector()) {
1618 if (ST->hasStdExtZvabd())
1620 getRISCVInstructionCost({RISCV::VABS_V}, LT.second,
CostKind);
1625 getRISCVInstructionCost({RISCV::VRSUB_VI, RISCV::VMAX_VV},
1630 case Intrinsic::fshl:
1631 case Intrinsic::fshr: {
1638 if ((ST->hasStdExtZbb() || ST->hasStdExtZbkb()) && RetTy->isIntegerTy() &&
1640 (RetTy->getIntegerBitWidth() == 32 ||
1641 RetTy->getIntegerBitWidth() == 64) &&
1642 RetTy->getIntegerBitWidth() <= ST->getXLen()) {
1647 case Intrinsic::clmul: {
1649 if (!LT.second.isVector() && ST->hasStdExtZvbc() && !ST->hasStdExtZbc() &&
1650 !ST->hasStdExtZbkc()) {
1653 if (!ST->is64Bit() || LT.second != MVT::i64)
1659 return LT.first * getRISCVInstructionCost(
1660 {RISCV::VMV_S_X, RISCV::VCLMUL_VX, RISCV::VMV_X_S},
1665 case Intrinsic::masked_udiv:
1668 case Intrinsic::masked_sdiv:
1671 case Intrinsic::masked_urem:
1674 case Intrinsic::masked_srem:
1677 case Intrinsic::get_active_lane_mask: {
1678 if (ST->hasVInstructions()) {
1687 getRISCVInstructionCost({RISCV::VSADDU_VX, RISCV::VMSLTU_VX},
1693 case Intrinsic::stepvector: {
1697 if (ST->hasVInstructions())
1698 return getRISCVInstructionCost(RISCV::VID_V, LT.second,
CostKind) +
1700 getRISCVInstructionCost(RISCV::VADD_VX, LT.second,
CostKind);
1701 return 1 + (LT.first - 1);
1703 case Intrinsic::vector_splice_left:
1704 case Intrinsic::vector_splice_right: {
1709 if (ST->hasVInstructions() && LT.second.isVector()) {
1711 getRISCVInstructionCost({RISCV::VSLIDEDOWN_VX, RISCV::VSLIDEUP_VX},
1716 case Intrinsic::experimental_cttz_elts: {
1717 if (getTLI()->shouldExpandCttzElements({}))
1724 if (LT.second.getVectorElementType() != MVT::i1)
1725 Cost += getRISCVInstructionCost(RISCV::VMSNE_VI, LT.second,
CostKind);
1727 Cost += getRISCVInstructionCost(RISCV::VFIRST_M, LT.second,
CostKind);
1739 return LT.first *
Cost;
1741 case Intrinsic::experimental_vp_splice: {
1749 case Intrinsic::vp_merge: {
1757 case Intrinsic::fptoui_sat:
1758 case Intrinsic::fptosi_sat: {
1760 bool IsSigned = ICA.
getID() == Intrinsic::fptosi_sat;
1765 if (!SrcTy->isVectorTy())
1768 if (!SrcLT.first.isValid() || !DstLT.first.isValid())
1785 case Intrinsic::experimental_vector_extract_last_active: {
1807 unsigned EltWidth = getTLI()->getBitWidthForCttzElements(
1808 TLI->getVectorIdxTy(
getDataLayout()), MaskTy->getElementCount(),
1809 true, &VScaleRange);
1810 EltWidth = std::max(EltWidth, MaskTy->getScalarSizeInBits());
1818 if (StepLT.first > 1)
1822 unsigned Opcodes[] = {RISCV::VID_V, RISCV::VREDMAXU_VS, RISCV::VMV_X_S};
1824 Cost += MaskLT.first *
1825 getRISCVInstructionCost(RISCV::VCPOP_M, MaskLT.second,
CostKind);
1827 Cost += StepLT.first *
1828 getRISCVInstructionCost(Opcodes, StepLT.second,
CostKind);
1832 Cost += ValLT.first *
1833 getRISCVInstructionCost({RISCV::VSLIDEDOWN_VI, RISCV::VMV_X_S},
1839 if (ST->hasVInstructions() && RetTy->isVectorTy()) {
1841 LT.second.isVector()) {
1842 MVT EltTy = LT.second.getVectorElementType();
1844 ICA.
getID(), EltTy))
1845 return LT.first * Entry->Cost;
1858 if (ST->hasVInstructions() && PtrTy->
isVectorTy())
1876 if (ST->hasStdExtP() &&
1884 if (!ST->hasVInstructions() || Src->getScalarSizeInBits() > ST->getELen() ||
1885 Dst->getScalarSizeInBits() > ST->getELen())
1888 int ISD = TLI->InstructionOpcodeToISD(Opcode);
1903 if (Src->getScalarSizeInBits() == 1) {
1908 return getRISCVInstructionCost(RISCV::VMV_V_I, DstLT.second,
CostKind) +
1909 DstLT.first * getRISCVInstructionCost(RISCV::VMERGE_VIM,
1915 if (Dst->getScalarSizeInBits() == 1) {
1921 return SrcLT.first *
1922 getRISCVInstructionCost({RISCV::VAND_VI, RISCV::VMSNE_VI},
1934 if (!SrcLT.second.isVector() || !DstLT.second.isVector() ||
1935 !SrcLT.first.isValid() || !DstLT.first.isValid() ||
1937 SrcLT.second.getSizeInBits()) ||
1939 DstLT.second.getSizeInBits()) ||
1940 SrcLT.first > 1 || DstLT.first > 1)
1944 assert((SrcLT.first == 1) && (DstLT.first == 1) &&
"Illegal type");
1946 int PowDiff = (int)
Log2_32(DstLT.second.getScalarSizeInBits()) -
1947 (int)
Log2_32(SrcLT.second.getScalarSizeInBits());
1951 if ((PowDiff < 1) || (PowDiff > 3))
1953 unsigned SExtOp[] = {RISCV::VSEXT_VF2, RISCV::VSEXT_VF4, RISCV::VSEXT_VF8};
1954 unsigned ZExtOp[] = {RISCV::VZEXT_VF2, RISCV::VZEXT_VF4, RISCV::VZEXT_VF8};
1957 return getRISCVInstructionCost(
Op, DstLT.second,
CostKind);
1963 unsigned SrcEltSize = SrcLT.second.getScalarSizeInBits();
1964 unsigned DstEltSize = DstLT.second.getScalarSizeInBits();
1968 : RISCV::VFNCVT_F_F_W;
1970 for (; SrcEltSize != DstEltSize;) {
1974 MVT DstMVT = DstLT.second.changeVectorElementType(ElementMVT);
1976 (DstEltSize > SrcEltSize) ? DstEltSize >> 1 : DstEltSize << 1;
1984 unsigned FCVT = IsSigned ? RISCV::VFCVT_RTZ_X_F_V : RISCV::VFCVT_RTZ_XU_F_V;
1986 IsSigned ? RISCV::VFWCVT_RTZ_X_F_V : RISCV::VFWCVT_RTZ_XU_F_V;
1988 IsSigned ? RISCV::VFNCVT_RTZ_X_F_W : RISCV::VFNCVT_RTZ_XU_F_W;
1989 unsigned SrcEltSize = Src->getScalarSizeInBits();
1990 unsigned DstEltSize = Dst->getScalarSizeInBits();
1992 if ((SrcEltSize == 16) &&
1993 (!ST->hasVInstructionsF16() || ((DstEltSize / 2) > SrcEltSize))) {
1999 std::pair<InstructionCost, MVT> VecF32LT =
2002 VecF32LT.first * getRISCVInstructionCost(RISCV::VFWCVT_F_F_V,
2007 if (DstEltSize == SrcEltSize)
2008 Cost += getRISCVInstructionCost(FCVT, DstLT.second,
CostKind);
2009 else if (DstEltSize > SrcEltSize)
2010 Cost += getRISCVInstructionCost(FWCVT, DstLT.second,
CostKind);
2015 MVT VecVT = DstLT.second.changeVectorElementType(ElementVT);
2016 Cost += getRISCVInstructionCost(FNCVT, VecVT,
CostKind);
2017 if ((SrcEltSize / 2) > DstEltSize) {
2028 unsigned FCVT = IsSigned ? RISCV::VFCVT_F_X_V : RISCV::VFCVT_F_XU_V;
2029 unsigned FWCVT = IsSigned ? RISCV::VFWCVT_F_X_V : RISCV::VFWCVT_F_XU_V;
2030 unsigned FNCVT = IsSigned ? RISCV::VFNCVT_F_X_W : RISCV::VFNCVT_F_XU_W;
2031 unsigned SrcEltSize = Src->getScalarSizeInBits();
2032 unsigned DstEltSize = Dst->getScalarSizeInBits();
2035 if ((DstEltSize == 16) &&
2036 (!ST->hasVInstructionsF16() || ((SrcEltSize / 2) > DstEltSize))) {
2042 std::pair<InstructionCost, MVT> VecF32LT =
2045 Cost += VecF32LT.first * getRISCVInstructionCost(RISCV::VFNCVT_F_F_W,
2050 if (DstEltSize == SrcEltSize)
2051 Cost += getRISCVInstructionCost(FCVT, DstLT.second,
CostKind);
2052 else if (DstEltSize > SrcEltSize) {
2053 if ((DstEltSize / 2) > SrcEltSize) {
2057 unsigned Op = IsSigned ? Instruction::SExt : Instruction::ZExt;
2060 Cost += getRISCVInstructionCost(FWCVT, DstLT.second,
CostKind);
2062 Cost += getRISCVInstructionCost(FNCVT, DstLT.second,
CostKind);
2069unsigned RISCVTTIImpl::getEstimatedVLFor(
VectorType *Ty)
const {
2071 const unsigned EltSize =
DL.getTypeSizeInBits(Ty->getElementType());
2072 const unsigned MinSize =
DL.getTypeSizeInBits(Ty).getKnownMinValue();
2087 if (Ty->getScalarSizeInBits() > ST->getELen())
2091 if (Ty->getElementType()->isIntegerTy(1)) {
2095 if (IID == Intrinsic::umax || IID == Intrinsic::smin)
2101 if (IID == Intrinsic::maximum || IID == Intrinsic::minimum) {
2105 case Intrinsic::maximum:
2107 Opcodes = {RISCV::VFREDMAX_VS, RISCV::VFMV_F_S};
2109 Opcodes = {RISCV::VMFNE_VV, RISCV::VCPOP_M, RISCV::VFREDMAX_VS,
2124 case Intrinsic::minimum:
2126 Opcodes = {RISCV::VFREDMIN_VS, RISCV::VFMV_F_S};
2128 Opcodes = {RISCV::VMFNE_VV, RISCV::VCPOP_M, RISCV::VFREDMIN_VS,
2134 const unsigned EltTyBits =
DL.getTypeSizeInBits(DstTy);
2143 return ExtraCost + getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2152 case Intrinsic::smax:
2153 SplitOp = RISCV::VMAX_VV;
2154 Opcodes = {RISCV::VREDMAX_VS, RISCV::VMV_X_S};
2156 case Intrinsic::smin:
2157 SplitOp = RISCV::VMIN_VV;
2158 Opcodes = {RISCV::VREDMIN_VS, RISCV::VMV_X_S};
2160 case Intrinsic::umax:
2161 SplitOp = RISCV::VMAXU_VV;
2162 Opcodes = {RISCV::VREDMAXU_VS, RISCV::VMV_X_S};
2164 case Intrinsic::umin:
2165 SplitOp = RISCV::VMINU_VV;
2166 Opcodes = {RISCV::VREDMINU_VS, RISCV::VMV_X_S};
2168 case Intrinsic::maxnum:
2169 SplitOp = RISCV::VFMAX_VV;
2170 Opcodes = {RISCV::VFREDMAX_VS, RISCV::VFMV_F_S};
2172 case Intrinsic::minnum:
2173 SplitOp = RISCV::VFMIN_VV;
2174 Opcodes = {RISCV::VFREDMIN_VS, RISCV::VFMV_F_S};
2179 (LT.first > 1) ? (LT.first - 1) *
2180 getRISCVInstructionCost(SplitOp, LT.second,
CostKind)
2182 return SplitCost + getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2187 std::optional<FastMathFlags> FMF,
2193 if (Ty->getScalarSizeInBits() > ST->getELen())
2196 int ISD = TLI->InstructionOpcodeToISD(Opcode);
2204 Type *ElementTy = Ty->getElementType();
2209 if (LT.second == MVT::v1i1)
2210 return getRISCVInstructionCost(RISCV::VFIRST_M, LT.second,
CostKind) +
2228 return ((LT.first > 2) ? (LT.first - 2) : 0) *
2229 getRISCVInstructionCost(RISCV::VMAND_MM, LT.second,
CostKind) +
2230 getRISCVInstructionCost(RISCV::VMNAND_MM, LT.second,
CostKind) +
2231 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind) +
2240 return (LT.first - 1) *
2241 getRISCVInstructionCost(RISCV::VMXOR_MM, LT.second,
CostKind) +
2242 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind) + 1;
2250 return (LT.first - 1) *
2251 getRISCVInstructionCost(RISCV::VMOR_MM, LT.second,
CostKind) +
2252 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind) +
2265 SplitOp = RISCV::VADD_VV;
2266 Opcodes = {RISCV::VMV_S_X, RISCV::VREDSUM_VS, RISCV::VMV_X_S};
2269 SplitOp = RISCV::VOR_VV;
2270 Opcodes = {RISCV::VREDOR_VS, RISCV::VMV_X_S};
2273 SplitOp = RISCV::VXOR_VV;
2274 Opcodes = {RISCV::VMV_S_X, RISCV::VREDXOR_VS, RISCV::VMV_X_S};
2277 SplitOp = RISCV::VAND_VV;
2278 Opcodes = {RISCV::VREDAND_VS, RISCV::VMV_X_S};
2282 if ((LT.second.getScalarType() == MVT::f16 && !ST->hasVInstructionsF16()) ||
2283 LT.second.getScalarType() == MVT::bf16)
2287 for (
unsigned i = 0; i < LT.first.getValue(); i++)
2290 return getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2292 SplitOp = RISCV::VFADD_VV;
2293 Opcodes = {RISCV::VFMV_S_F, RISCV::VFREDUSUM_VS, RISCV::VFMV_F_S};
2298 (LT.first > 1) ? (LT.first - 1) *
2299 getRISCVInstructionCost(SplitOp, LT.second,
CostKind)
2301 return SplitCost + getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2305 unsigned Opcode,
bool IsUnsigned,
Type *ResTy,
VectorType *ValTy,
2316 if (Opcode != Instruction::Add && Opcode != Instruction::FAdd)
2322 if (IsUnsigned && Opcode == Instruction::Add &&
2323 LT.second.isFixedLengthVectorOf(MVT::i1)) {
2327 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind);
2334 return (LT.first - 1) +
2341 assert(OpInfo.isConstant() &&
"non constant operand?");
2348 if (OpInfo.isUniform())
2354 return getConstantPoolLoadCost(Ty,
CostKind);
2363 EVT VT = TLI->getValueType(
DL, Src,
true);
2365 if (VT == MVT::Other ||
2371 if (Opcode == Instruction::Store && OpInfo.isConstant())
2386 if (Src->
isVectorTy() && LT.second.isVector() &&
2388 LT.second.getSizeInBits()))
2398 if (ST->hasVInstructions() && LT.second.isVector() &&
2400 BaseCost *= TLI->getLMULCost(LT.second);
2401 return Cost + BaseCost;
2410 Op1Info, Op2Info,
I);
2414 Op1Info, Op2Info,
I);
2419 Op1Info, Op2Info,
I);
2421 auto GetConstantMatCost =
2423 if (OpInfo.isUniform())
2428 return getConstantPoolLoadCost(ValTy,
CostKind);
2433 ConstantMatCost += GetConstantMatCost(Op1Info);
2435 ConstantMatCost += GetConstantMatCost(Op2Info);
2438 if (Opcode == Instruction::Select && LT.second.isVector()) {
2439 if (CondTy->isVectorTy()) {
2444 return ConstantMatCost +
2446 getRISCVInstructionCost(
2447 {RISCV::VMANDN_MM, RISCV::VMAND_MM, RISCV::VMOR_MM},
2451 return ConstantMatCost +
2452 LT.first * getRISCVInstructionCost(RISCV::VMERGE_VVM, LT.second,
2462 MVT InterimVT = LT.second.changeVectorElementType(MVT::i8);
2463 return ConstantMatCost +
2465 getRISCVInstructionCost({RISCV::VMV_V_X, RISCV::VMSNE_VI},
2467 LT.first * getRISCVInstructionCost(
2468 {RISCV::VMANDN_MM, RISCV::VMAND_MM, RISCV::VMOR_MM},
2475 return ConstantMatCost +
2476 LT.first * getRISCVInstructionCost(
2477 {RISCV::VMV_V_X, RISCV::VMSNE_VI, RISCV::VMERGE_VVM},
2481 if ((Opcode == Instruction::ICmp) && ValTy->
isVectorTy() &&
2485 return ConstantMatCost + LT.first * getRISCVInstructionCost(RISCV::VMSLT_VV,
2490 if ((Opcode == Instruction::FCmp) && ValTy->
isVectorTy() &&
2495 return ConstantMatCost +
2496 getRISCVInstructionCost(RISCV::VMXOR_MM, LT.second,
CostKind);
2506 Op1Info, Op2Info,
I);
2515 return ConstantMatCost +
2516 LT.first * getRISCVInstructionCost(
2517 {RISCV::VMFLT_VV, RISCV::VMFLT_VV, RISCV::VMOR_MM},
2524 return ConstantMatCost +
2526 getRISCVInstructionCost({RISCV::VMFLT_VV, RISCV::VMNAND_MM},
2535 return ConstantMatCost +
2537 getRISCVInstructionCost(RISCV::VMFLT_VV, LT.second,
CostKind);
2550 return match(U, m_Select(m_Specific(I), m_Value(), m_Value())) &&
2551 U->getType()->isIntegerTy() &&
2552 !isa<ConstantData>(U->getOperand(1)) &&
2553 !isa<ConstantData>(U->getOperand(2));
2561 Op1Info, Op2Info,
I);
2568 return Opcode == Instruction::PHI ? 0 : 1;
2585 if (Opcode != Instruction::ExtractElement &&
2586 Opcode != Instruction::InsertElement)
2594 if (!LT.second.isVector()) {
2603 Type *ElemTy = FixedVecTy->getElementType();
2604 auto NumElems = FixedVecTy->getNumElements();
2605 auto Align =
DL.getPrefTypeAlign(ElemTy);
2610 return Opcode == Instruction::ExtractElement
2611 ? StoreCost * NumElems + LoadCost
2612 : (StoreCost + LoadCost) * NumElems + StoreCost;
2616 if (LT.second.isScalableVector() && !LT.first.isValid())
2624 if (Opcode == Instruction::ExtractElement) {
2630 return ExtendCost + ExtractCost;
2640 return ExtendCost + InsertCost + TruncCost;
2647 if (LT.second.isFloatingPoint())
2648 MoveOpc = Opcode == Instruction::InsertElement ? RISCV::VFMV_S_F
2652 Opcode == Instruction::InsertElement ? RISCV::VMV_S_X : RISCV::VMV_X_S;
2654 getRISCVInstructionCost(MoveOpc, LT.second,
CostKind);
2656 InstructionCost SlideCost = Opcode == Instruction::InsertElement ? 2 : 1;
2661 if (LT.second.isFixedLengthVector()) {
2662 unsigned Width = LT.second.getVectorNumElements();
2663 Index = Index % Width;
2668 if (
auto VLEN = ST->getRealVLen()) {
2669 unsigned EltSize = LT.second.getScalarSizeInBits();
2670 unsigned M1Max = *VLEN / EltSize;
2671 Index = Index % M1Max;
2677 else if (Opcode == Instruction::InsertElement)
2685 ((Index == -1U) || (Index >= LT.second.getVectorMinNumElements() &&
2686 LT.second.isScalableVector()))) {
2688 Align VecAlign =
DL.getPrefTypeAlign(Val);
2689 Align SclAlign =
DL.getPrefTypeAlign(ScalarType);
2694 if (Opcode == Instruction::ExtractElement)
2730 Opcode == Instruction::InsertElement
2731 ? getRISCVInstructionCost({RISCV::VSLIDE1DOWN_VX,
2732 RISCV::VSLIDE1DOWN_VX,
2733 RISCV::VSLIDEUP_VX},
2735 : getRISCVInstructionCost({RISCV::VSLIDEDOWN_VX, RISCV::VMV_X_S,
2736 RISCV::VSRL_VX, RISCV::VMV_X_S},
2739 return BaseCost + SlideCost;
2745 unsigned Index)
const {
2754 assert(Index < EC.getKnownMinValue() &&
"Unexpected reverse index");
2756 EC.getKnownMinValue() - 1 - Index,
nullptr,
2765std::optional<InstructionCost>
2771 if ((Opcode == Instruction::UDiv || Opcode == Instruction::URem) &&
2773 if (Opcode == Instruction::UDiv)
2780 return std::nullopt;
2802 if (std::optional<InstructionCost> CombinedCost =
2804 Op2Info, Args, CxtI))
2805 return *CombinedCost;
2809 unsigned ISDOpcode = TLI->InstructionOpcodeToISD(Opcode);
2812 if (!LT.second.isVector()) {
2822 if (TLI->isOperationLegalOrPromote(ISDOpcode, LT.second))
2823 if (
const auto *Entry =
CostTableLookup(DivTbl, ISDOpcode, LT.second))
2824 return Entry->Cost * LT.first;
2833 if ((LT.second.getVectorElementType() == MVT::f16 ||
2834 LT.second.getVectorElementType() == MVT::bf16) &&
2835 TLI->getOperationAction(ISDOpcode, LT.second) ==
2837 MVT PromotedVT = TLI->getTypeToPromoteTo(ISDOpcode, LT.second);
2841 CastCost += LT.first * Args.size() *
2849 LT.second = PromotedVT;
2852 auto getConstantMatCost =
2862 return getConstantPoolLoadCost(Ty,
CostKind);
2868 ConstantMatCost += getConstantMatCost(0, Op1Info);
2870 ConstantMatCost += getConstantMatCost(1, Op2Info);
2873 switch (ISDOpcode) {
2876 Op = RISCV::VADD_VV;
2881 Op = RISCV::VSLL_VV;
2886 Op = (Ty->getScalarSizeInBits() == 1) ? RISCV::VMAND_MM : RISCV::VAND_VV;
2891 Op = RISCV::VMUL_VV;
2895 Op = RISCV::VDIV_VV;
2899 Op = RISCV::VREM_VV;
2903 Op = RISCV::VFADD_VV;
2906 Op = RISCV::VFMUL_VV;
2909 Op = RISCV::VFDIV_VV;
2912 Op = RISCV::VFSGNJN_VV;
2917 return CastCost + ConstantMatCost +
2926 if (Ty->isFPOrFPVectorTy())
2928 return CastCost + ConstantMatCost + LT.first *
InstrCost;
2951 if (Info.isSameBase() && V !=
Base) {
2952 if (
GEP->hasAllConstantIndices())
2958 unsigned Stride =
DL.getTypeStoreSize(AccessTy);
2959 if (Info.isUnitStride() &&
2965 GEP->getType()->getPointerAddressSpace()))
2968 {TTI::OK_AnyValue, TTI::OP_None},
2969 {TTI::OK_AnyValue, TTI::OP_None}, {});
2986 if (ST->enableDefaultUnroll())
2996 if (L->getHeader()->getParent()->hasOptSize())
3000 L->getExitingBlocks(ExitingBlocks);
3002 <<
"Blocks: " << L->getNumBlocks() <<
"\n"
3003 <<
"Exit blocks: " << ExitingBlocks.
size() <<
"\n");
3007 if (ExitingBlocks.
size() > 2)
3012 if (L->getNumBlocks() > 4)
3020 for (
auto *BB : L->getBlocks()) {
3021 for (
auto &
I : *BB) {
3025 if (IsVectorized && (
I.getType()->isVectorTy() ||
3027 return V->getType()->isVectorTy();
3068 bool HasMask =
false;
3071 bool IsWrite) -> int64_t {
3072 if (
auto *TarExtTy =
3074 return TarExtTy->getIntParameter(0);
3080 case Intrinsic::riscv_vle_mask:
3081 case Intrinsic::riscv_vse_mask:
3082 case Intrinsic::riscv_vlseg2_mask:
3083 case Intrinsic::riscv_vlseg3_mask:
3084 case Intrinsic::riscv_vlseg4_mask:
3085 case Intrinsic::riscv_vlseg5_mask:
3086 case Intrinsic::riscv_vlseg6_mask:
3087 case Intrinsic::riscv_vlseg7_mask:
3088 case Intrinsic::riscv_vlseg8_mask:
3089 case Intrinsic::riscv_vsseg2_mask:
3090 case Intrinsic::riscv_vsseg3_mask:
3091 case Intrinsic::riscv_vsseg4_mask:
3092 case Intrinsic::riscv_vsseg5_mask:
3093 case Intrinsic::riscv_vsseg6_mask:
3094 case Intrinsic::riscv_vsseg7_mask:
3095 case Intrinsic::riscv_vsseg8_mask:
3098 case Intrinsic::riscv_vle:
3099 case Intrinsic::riscv_vse:
3100 case Intrinsic::riscv_vlseg2:
3101 case Intrinsic::riscv_vlseg3:
3102 case Intrinsic::riscv_vlseg4:
3103 case Intrinsic::riscv_vlseg5:
3104 case Intrinsic::riscv_vlseg6:
3105 case Intrinsic::riscv_vlseg7:
3106 case Intrinsic::riscv_vlseg8:
3107 case Intrinsic::riscv_vsseg2:
3108 case Intrinsic::riscv_vsseg3:
3109 case Intrinsic::riscv_vsseg4:
3110 case Intrinsic::riscv_vsseg5:
3111 case Intrinsic::riscv_vsseg6:
3112 case Intrinsic::riscv_vsseg7:
3113 case Intrinsic::riscv_vsseg8: {
3130 Ty = TarExtTy->getTypeParameter(0U);
3135 const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
3136 unsigned VLIndex = RVVIInfo->VLOperand;
3137 unsigned PtrOperandNo = VLIndex - 1 - HasMask;
3145 unsigned SegNum = getSegNum(Inst, PtrOperandNo, IsWrite);
3148 unsigned ElemSize = Ty->getScalarSizeInBits();
3152 Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty,
3153 Alignment, Mask, EVL);
3156 case Intrinsic::riscv_vlse_mask:
3157 case Intrinsic::riscv_vsse_mask:
3158 case Intrinsic::riscv_vlsseg2_mask:
3159 case Intrinsic::riscv_vlsseg3_mask:
3160 case Intrinsic::riscv_vlsseg4_mask:
3161 case Intrinsic::riscv_vlsseg5_mask:
3162 case Intrinsic::riscv_vlsseg6_mask:
3163 case Intrinsic::riscv_vlsseg7_mask:
3164 case Intrinsic::riscv_vlsseg8_mask:
3165 case Intrinsic::riscv_vssseg2_mask:
3166 case Intrinsic::riscv_vssseg3_mask:
3167 case Intrinsic::riscv_vssseg4_mask:
3168 case Intrinsic::riscv_vssseg5_mask:
3169 case Intrinsic::riscv_vssseg6_mask:
3170 case Intrinsic::riscv_vssseg7_mask:
3171 case Intrinsic::riscv_vssseg8_mask:
3174 case Intrinsic::riscv_vlse:
3175 case Intrinsic::riscv_vsse:
3176 case Intrinsic::riscv_vlsseg2:
3177 case Intrinsic::riscv_vlsseg3:
3178 case Intrinsic::riscv_vlsseg4:
3179 case Intrinsic::riscv_vlsseg5:
3180 case Intrinsic::riscv_vlsseg6:
3181 case Intrinsic::riscv_vlsseg7:
3182 case Intrinsic::riscv_vlsseg8:
3183 case Intrinsic::riscv_vssseg2:
3184 case Intrinsic::riscv_vssseg3:
3185 case Intrinsic::riscv_vssseg4:
3186 case Intrinsic::riscv_vssseg5:
3187 case Intrinsic::riscv_vssseg6:
3188 case Intrinsic::riscv_vssseg7:
3189 case Intrinsic::riscv_vssseg8: {
3206 Ty = TarExtTy->getTypeParameter(0U);
3211 const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
3212 unsigned VLIndex = RVVIInfo->VLOperand;
3213 unsigned PtrOperandNo = VLIndex - 2 - HasMask;
3225 Alignment =
Align(1);
3232 unsigned SegNum = getSegNum(Inst, PtrOperandNo, IsWrite);
3235 unsigned ElemSize = Ty->getScalarSizeInBits();
3239 Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty,
3240 Alignment, Mask, EVL, Stride);
3243 case Intrinsic::riscv_vloxei_mask:
3244 case Intrinsic::riscv_vluxei_mask:
3245 case Intrinsic::riscv_vsoxei_mask:
3246 case Intrinsic::riscv_vsuxei_mask:
3247 case Intrinsic::riscv_vloxseg2_mask:
3248 case Intrinsic::riscv_vloxseg3_mask:
3249 case Intrinsic::riscv_vloxseg4_mask:
3250 case Intrinsic::riscv_vloxseg5_mask:
3251 case Intrinsic::riscv_vloxseg6_mask:
3252 case Intrinsic::riscv_vloxseg7_mask:
3253 case Intrinsic::riscv_vloxseg8_mask:
3254 case Intrinsic::riscv_vluxseg2_mask:
3255 case Intrinsic::riscv_vluxseg3_mask:
3256 case Intrinsic::riscv_vluxseg4_mask:
3257 case Intrinsic::riscv_vluxseg5_mask:
3258 case Intrinsic::riscv_vluxseg6_mask:
3259 case Intrinsic::riscv_vluxseg7_mask:
3260 case Intrinsic::riscv_vluxseg8_mask:
3261 case Intrinsic::riscv_vsoxseg2_mask:
3262 case Intrinsic::riscv_vsoxseg3_mask:
3263 case Intrinsic::riscv_vsoxseg4_mask:
3264 case Intrinsic::riscv_vsoxseg5_mask:
3265 case Intrinsic::riscv_vsoxseg6_mask:
3266 case Intrinsic::riscv_vsoxseg7_mask:
3267 case Intrinsic::riscv_vsoxseg8_mask:
3268 case Intrinsic::riscv_vsuxseg2_mask:
3269 case Intrinsic::riscv_vsuxseg3_mask:
3270 case Intrinsic::riscv_vsuxseg4_mask:
3271 case Intrinsic::riscv_vsuxseg5_mask:
3272 case Intrinsic::riscv_vsuxseg6_mask:
3273 case Intrinsic::riscv_vsuxseg7_mask:
3274 case Intrinsic::riscv_vsuxseg8_mask:
3277 case Intrinsic::riscv_vloxei:
3278 case Intrinsic::riscv_vluxei:
3279 case Intrinsic::riscv_vsoxei:
3280 case Intrinsic::riscv_vsuxei:
3281 case Intrinsic::riscv_vloxseg2:
3282 case Intrinsic::riscv_vloxseg3:
3283 case Intrinsic::riscv_vloxseg4:
3284 case Intrinsic::riscv_vloxseg5:
3285 case Intrinsic::riscv_vloxseg6:
3286 case Intrinsic::riscv_vloxseg7:
3287 case Intrinsic::riscv_vloxseg8:
3288 case Intrinsic::riscv_vluxseg2:
3289 case Intrinsic::riscv_vluxseg3:
3290 case Intrinsic::riscv_vluxseg4:
3291 case Intrinsic::riscv_vluxseg5:
3292 case Intrinsic::riscv_vluxseg6:
3293 case Intrinsic::riscv_vluxseg7:
3294 case Intrinsic::riscv_vluxseg8:
3295 case Intrinsic::riscv_vsoxseg2:
3296 case Intrinsic::riscv_vsoxseg3:
3297 case Intrinsic::riscv_vsoxseg4:
3298 case Intrinsic::riscv_vsoxseg5:
3299 case Intrinsic::riscv_vsoxseg6:
3300 case Intrinsic::riscv_vsoxseg7:
3301 case Intrinsic::riscv_vsoxseg8:
3302 case Intrinsic::riscv_vsuxseg2:
3303 case Intrinsic::riscv_vsuxseg3:
3304 case Intrinsic::riscv_vsuxseg4:
3305 case Intrinsic::riscv_vsuxseg5:
3306 case Intrinsic::riscv_vsuxseg6:
3307 case Intrinsic::riscv_vsuxseg7:
3308 case Intrinsic::riscv_vsuxseg8: {
3325 Ty = TarExtTy->getTypeParameter(0U);
3330 const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
3331 unsigned VLIndex = RVVIInfo->VLOperand;
3332 unsigned PtrOperandNo = VLIndex - 2 - HasMask;
3345 unsigned SegNum = getSegNum(Inst, PtrOperandNo, IsWrite);
3348 unsigned ElemSize = Ty->getScalarSizeInBits();
3353 Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty,
3354 Align(1), Mask, EVL,
3363 if (Ty->isVectorTy()) {
3366 if ((EltTy->
isHalfTy() && !ST->hasVInstructionsF16()) ||
3372 if (
Size.isScalable() && ST->hasVInstructions())
3375 if (ST->useRVVForFixedLengthVectors())
3395 return std::max<unsigned>(1U, RegWidth.
getFixedValue() / ElemWidth);
3403 return ST->enableUnalignedVectorMem();
3409 if (ST->hasVendorXCVmem() && !ST->is64Bit())
3431 Align Alignment)
const {
3433 if (!VTy || VTy->isScalableTy())
3441 if (VTy->getElementType()->isIntegerTy(8))
3442 if (VTy->getElementCount().getFixedValue() > 256)
3443 return VTy->getPrimitiveSizeInBits() / ST->getRealMinVLen() <
3444 ST->getMaxLMULForFixedLengthVectors();
3449 Align Alignment)
const {
3451 if (!VTy || VTy->isScalableTy())
3462 if (!ST->hasVInstructions() || !ST->hasOptimizedZeroStrideLoad())
3465 return TLI->isLegalElementTypeForRVV(TLI->getValueType(
DL, ElementTy));
3474 const Instruction &
I,
bool &AllowPromotionWithoutCommonHeader)
const {
3475 bool Considerable =
false;
3476 AllowPromotionWithoutCommonHeader =
false;
3479 Type *ConsideredSExtType =
3481 if (
I.getType() != ConsideredSExtType)
3485 for (
const User *U :
I.users()) {
3487 Considerable =
true;
3491 if (GEPInst->getNumOperands() > 2) {
3492 AllowPromotionWithoutCommonHeader =
true;
3497 return Considerable;
3502 case Instruction::Add:
3503 case Instruction::Sub:
3504 case Instruction::Mul:
3505 case Instruction::And:
3506 case Instruction::Or:
3507 case Instruction::Xor:
3508 case Instruction::FAdd:
3509 case Instruction::FSub:
3510 case Instruction::FMul:
3511 case Instruction::FDiv:
3512 case Instruction::ICmp:
3513 case Instruction::FCmp:
3515 case Instruction::Shl:
3516 case Instruction::LShr:
3517 case Instruction::AShr:
3518 case Instruction::UDiv:
3519 case Instruction::SDiv:
3520 case Instruction::URem:
3521 case Instruction::SRem:
3522 case Instruction::Select:
3523 return Operand == 1;
3530 if (!
I->getType()->isVectorTy() || !ST->hasVInstructions())
3540 switch (
II->getIntrinsicID()) {
3541 case Intrinsic::fma:
3542 case Intrinsic::vp_fma:
3543 case Intrinsic::fmuladd:
3544 case Intrinsic::vp_fmuladd:
3545 return Operand == 0 || Operand == 1;
3546 case Intrinsic::vp_shl:
3547 case Intrinsic::vp_lshr:
3548 case Intrinsic::vp_ashr:
3549 case Intrinsic::vp_udiv:
3550 case Intrinsic::vp_sdiv:
3551 case Intrinsic::vp_urem:
3552 case Intrinsic::vp_srem:
3553 case Intrinsic::ssub_sat:
3554 case Intrinsic::vp_ssub_sat:
3555 case Intrinsic::usub_sat:
3556 case Intrinsic::vp_usub_sat:
3557 case Intrinsic::vp_select:
3558 return Operand == 1;
3560 case Intrinsic::vp_add:
3561 case Intrinsic::vp_mul:
3562 case Intrinsic::vp_and:
3563 case Intrinsic::vp_or:
3564 case Intrinsic::vp_xor:
3565 case Intrinsic::vp_fadd:
3566 case Intrinsic::vp_fmul:
3567 case Intrinsic::vp_icmp:
3568 case Intrinsic::vp_fcmp:
3569 case Intrinsic::smin:
3570 case Intrinsic::vp_smin:
3571 case Intrinsic::umin:
3572 case Intrinsic::vp_umin:
3573 case Intrinsic::smax:
3574 case Intrinsic::vp_smax:
3575 case Intrinsic::umax:
3576 case Intrinsic::vp_umax:
3577 case Intrinsic::sadd_sat:
3578 case Intrinsic::vp_sadd_sat:
3579 case Intrinsic::uadd_sat:
3580 case Intrinsic::vp_uadd_sat:
3582 case Intrinsic::vp_sub:
3583 case Intrinsic::vp_fsub:
3584 case Intrinsic::vp_fdiv:
3585 return Operand == 0 || Operand == 1;
3598 if (
I->isBitwiseLogicOp()) {
3599 if (!
I->getType()->isVectorTy()) {
3600 if (ST->hasStdExtZbb() || ST->hasStdExtZbkb()) {
3601 for (
auto &
Op :
I->operands()) {
3609 }
else if (
I->getOpcode() == Instruction::And && ST->hasStdExtZvkb()) {
3610 for (
auto &
Op :
I->operands()) {
3622 Ops.push_back(&Not);
3623 Ops.push_back(&InsertElt);
3631 if (!
I->getType()->isVectorTy() || !ST->hasVInstructions())
3639 if (!ST->sinkSplatOperands())
3642 for (
auto OpIdx :
enumerate(
I->operands())) {
3662 for (
Use &U :
Op->uses()) {
3669 Use *InsertEltUse = &
Op->getOperandUse(0);
3672 Ops.push_back(&InsertElt->getOperandUse(1));
3673 Ops.push_back(InsertEltUse);
3674 Ops.push_back(&OpIdx.value());
3683 if (!ST->hasStdExtZbb() && !ST->hasStdExtZbkb() && !IsZeroCmp)
3686 Options.AllowOverlappingLoads =
true;
3687 Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize);
3689 if (ST->is64Bit()) {
3690 Options.LoadSizes = {8, 4, 2, 1};
3691 Options.AllowedTailExpansions = {3, 5, 6};
3693 Options.LoadSizes = {4, 2, 1};
3694 Options.AllowedTailExpansions = {3};
3697 if (IsZeroCmp && ST->hasVInstructions()) {
3698 unsigned VLenB = ST->getRealMinVLen() / 8;
3701 unsigned MinSize = ST->getXLen() / 8 + 1;
3702 unsigned MaxSize = VLenB * ST->getMaxLMULForFixedLengthVectors();
3716 if (
I->getOpcode() == Instruction::Or &&
3720 if (
I->getOpcode() == Instruction::Add ||
3721 I->getOpcode() == Instruction::Sub)
3739std::optional<Instruction *>
3745 if (
II.user_empty())
3750 const APInt *Scalar;
3755 return U->getType() == TargetVecTy && match(U, m_BitCast(m_Value()));
3759 unsigned TargetEltBW =
DL.getTypeSizeInBits(TargetVecTy->getElementType());
3760 unsigned SourceEltBW =
DL.getTypeSizeInBits(SourceVecTy->getElementType());
3761 if (TargetEltBW % SourceEltBW)
3763 unsigned TargetScale = TargetEltBW / SourceEltBW;
3764 if (VL % TargetScale || TargetScale == 1)
3766 Type *VLTy =
II.getOperand(2)->getType();
3767 ElementCount SourceEC = SourceVecTy->getElementCount();
3768 unsigned NewEltBW = SourceEltBW * TargetScale;
3770 !
DL.fitsInLegalInteger(NewEltBW))
3773 if (!TLI->isLegalElementTypeForRVV(TLI->getValueType(
DL, NewEltTy)))
3777 assert(SourceVecTy->canLosslesslyBitCastTo(RetTy) &&
3778 "Lossless bitcast between types expected");
3784 RetTy, Intrinsic::riscv_vmv_v_x,
3785 {PoisonValue::get(RetTy), ConstantInt::get(NewEltTy, NewScalar),
3786 ConstantInt::get(VLTy, VL / TargetScale)}),
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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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.
This file provides the interface for the instcombine pass implementation.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static const Function * getCalledFunction(const Value *V)
uint64_t IntrinsicInst * II
static Type * getValueType(Value *V, bool LookThroughCmp=false)
Returns the "element type" of the given value/instruction V.
This file describes how to lower LLVM code to machine code.
Class for arbitrary precision integers.
static LLVM_ABI APInt getSplat(unsigned NewLen, const APInt &V)
Return a value containing V broadcasted over NewLen bits.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & back() const
Get the last element.
size_t size() const
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)
This class represents a range of values.
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
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
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.
The core instruction combiner logic.
const DataLayout & getDataLayout() const
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
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
VectorInstrContext getVectorInstrContext() 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.
static MVT getScalableVectorVT(MVT VT, unsigned NumElements)
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
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
std::optional< InstructionCost > getCombinedArithmeticInstructionCost(unsigned ISDOpcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Opd1Info, TTI::OperandValueInfo Opd2Info, ArrayRef< const Value * > Args, const Instruction *CxtI) const
Check to see if this instruction is expected to be combined to a simpler operation during/before lowe...
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
bool isLegalBroadcastLoad(Type *ElementTy, ElementCount NumElements) 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
std::optional< Instruction * > instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) 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.
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.
auto m_Poison()
Match an arbitrary poison constant.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
bool match(Val *V, const Pattern &P)
auto m_Value()
Match an arbitrary value 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.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
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.
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.
@ BinaryOp
One of the operands is a binary op.
auto adjacent_find(R &&Range)
Provide wrappers to std::adjacent_find which finds the first pair of adjacent elements that are equal...
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.
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
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
OutputIt copy(R &&Range, OutputIt Out)
CostTblEntryT< uint16_t > CostTblEntry
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.