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(
250 Ty->getContext(),
DL, getTLI()->getValueType(
DL, Ty),
257 case Instruction::Load:
260 case Instruction::And:
262 if (
Imm == UINT64_C(0xffff) && ST->hasStdExtZbb())
265 if (
Imm == UINT64_C(0xffffffff) && (!ST->is64Bit() || ST->hasStdExtZba()))
268 if (ST->hasStdExtZbs() && (~
Imm).isPowerOf2())
270 if (Inst && Idx == 1 &&
Imm.getBitWidth() <= ST->getXLen() &&
273 if (Inst && Idx == 1 &&
Imm.getBitWidth() == 64 &&
276 Takes12BitImm =
true;
278 case Instruction::Add:
279 Takes12BitImm =
true;
281 case Instruction::Or:
282 case Instruction::Xor:
284 if (ST->hasStdExtZbs() &&
Imm.isPowerOf2())
286 Takes12BitImm =
true;
288 case Instruction::Mul:
290 if (
Imm.isPowerOf2() ||
Imm.isNegatedPowerOf2())
293 if ((
Imm + 1).isPowerOf2() || (
Imm - 1).isPowerOf2())
296 Takes12BitImm =
true;
298 case Instruction::Sub:
299 case Instruction::Shl:
300 case Instruction::LShr:
301 case Instruction::AShr:
302 Takes12BitImm =
true;
313 if (
Imm.getSignificantBits() <= 64 &&
336 return ST->hasVInstructions();
346 unsigned Opcode,
Type *InputTypeA,
Type *InputTypeB,
Type *AccumType,
350 if (Opcode == Instruction::FAdd)
359 if (!ST->hasStdExtZvdot4a8i() || ST->getELen() < 64 ||
360 Opcode != Instruction::Add || !BinOp || *BinOp != Instruction::Mul ||
361 InputTypeA != InputTypeB || !InputTypeA->
isIntegerTy(8) ||
377 getRISCVInstructionCost(RISCV::VDOT4A_VV, DotLT.second,
CostKind);
386 std::pair<InstructionCost, MVT> AccLT =
394 bool WidenFirst =
false;
395 if (VF.
isScalable() && AccLT.second.isScalableVector()) {
396 MVT NarrowMVT = AccLT.second.changeVectorElementType(MVT::i32);
409 WideLT.first * getRISCVInstructionCost(RISCV::VSEXT_VF2,
412 getRISCVInstructionCost(RISCV::VADD_VV, AccLT.second,
CostKind);
416 std::pair<InstructionCost, MVT> RedLT =
418 Cost += RedLT.first * getRISCVInstructionCost(RISCV::VADD_VV,
420 AccLT.first * getRISCVInstructionCost(RISCV::VWADD_WV,
424 Cost += DotLT.first * getRISCVInstructionCost(RISCV::VSLIDEDOWN_VI,
436 switch (
II->getIntrinsicID()) {
440 case Intrinsic::vector_reduce_mul:
441 case Intrinsic::vector_reduce_fmul:
447 if (ST->hasVInstructions())
448 if (
unsigned MinVLen = ST->getRealMinVLen();
463 ST->useRVVForFixedLengthVectors() ? LMUL * ST->getRealMinVLen() : 0);
466 (ST->hasVInstructions() &&
489 return (ST->hasAUIPCADDIFusion() && ST->hasLUIADDIFusion()) ? 1 : 2;
495RISCVTTIImpl::getConstantPoolLoadCost(
Type *Ty,
500 return getStaticDataAddrGenerationCost(
CostKind) +
506 unsigned Size = Mask.size();
509 for (
unsigned I = 0;
I !=
Size; ++
I) {
510 if (
static_cast<unsigned>(Mask[
I]) ==
I)
516 for (
unsigned J =
I + 1; J !=
Size; ++J)
518 if (
static_cast<unsigned>(Mask[J]) != J %
I)
546 "Expected fixed vector type and non-empty mask");
549 unsigned NumOfDests =
divideCeil(Mask.size(), LegalNumElts);
553 if (NumOfDests <= 1 ||
555 Tp->getElementType()->getPrimitiveSizeInBits() ||
556 LegalNumElts >= Tp->getElementCount().getFixedValue())
559 unsigned VecTySize =
TTI.getDataLayout().getTypeStoreSize(Tp);
562 unsigned NumOfSrcs =
divideCeil(VecTySize, LegalVTSize);
566 unsigned NormalizedVF = LegalNumElts * std::max(NumOfSrcs, NumOfDests);
567 unsigned NumOfSrcRegs = NormalizedVF / LegalNumElts;
568 unsigned NumOfDestRegs = NormalizedVF / LegalNumElts;
570 assert(NormalizedVF >= Mask.size() &&
571 "Normalized mask expected to be not shorter than original mask.");
576 NormalizedMask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, []() {},
577 [&](
ArrayRef<int> RegMask,
unsigned SrcReg,
unsigned DestReg) {
580 if (!ReusedSingleSrcShuffles.
insert(std::make_pair(RegMask, SrcReg))
583 Cost +=
TTI.getShuffleCost(
586 SingleOpTy,
CostKind, RegMask, 0,
nullptr);
588 [&](
ArrayRef<int> RegMask,
unsigned Idx1,
unsigned Idx2,
bool NewReg) {
589 Cost +=
TTI.getShuffleCost(
592 SingleOpTy,
CostKind, RegMask, 0,
nullptr);
615 if (!VLen || Mask.empty())
619 LegalVT =
TTI.getTypeLegalizationCost(
625 if (NumOfDests <= 1 ||
627 Tp->getElementType()->getPrimitiveSizeInBits() ||
631 unsigned VecTySize =
TTI.getDataLayout().getTypeStoreSize(Tp);
634 unsigned NumOfSrcs =
divideCeil(VecTySize, LegalVTSize);
640 unsigned NormalizedVF =
645 assert(NormalizedVF >= Mask.size() &&
646 "Normalized mask expected to be not shorter than original mask.");
652 NormalizedMask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, []() {},
653 [&](
ArrayRef<int> RegMask,
unsigned SrcReg,
unsigned DestReg) {
656 if (!ReusedSingleSrcShuffles.
insert(std::make_pair(RegMask, SrcReg))
661 SingleOpTy,
CostKind, RegMask, 0,
nullptr);
663 [&](
ArrayRef<int> RegMask,
unsigned Idx1,
unsigned Idx2,
bool NewReg) {
665 SingleOpTy,
CostKind, RegMask, 0,
nullptr);
672 if ((NumOfDestRegs > 2 && NumShuffles <=
static_cast<int>(NumOfDestRegs)) ||
673 (NumOfDestRegs <= 2 && NumShuffles < 4))
688 if (!
LT.second.isFixedLengthVector())
696 auto GetSlideOpcode = [&](
int SlideAmt) {
698 bool IsVI =
isUInt<5>(std::abs(SlideAmt));
700 return IsVI ? RISCV::VSLIDEDOWN_VI : RISCV::VSLIDEDOWN_VX;
701 return IsVI ? RISCV::VSLIDEUP_VI : RISCV::VSLIDEUP_VX;
704 std::array<std::pair<int, int>, 2> SrcInfo;
708 if (SrcInfo[1].second == 0)
712 if (SrcInfo[0].second != 0) {
713 unsigned Opcode = GetSlideOpcode(SrcInfo[0].second);
714 FirstSlideCost = getRISCVInstructionCost(Opcode,
LT.second,
CostKind);
717 if (SrcInfo[1].first == -1)
718 return FirstSlideCost;
721 if (SrcInfo[1].second != 0) {
722 unsigned Opcode = GetSlideOpcode(SrcInfo[1].second);
723 SecondSlideCost = getRISCVInstructionCost(Opcode,
LT.second,
CostKind);
726 getRISCVInstructionCost(RISCV::VMERGE_VVM,
LT.second,
CostKind);
733 return FirstSlideCost + SecondSlideCost + MaskCost;
744 "Expected the Mask to match the return size if given");
746 "Expected the same scalar types");
762 FVTp && ST->hasVInstructions() && LT.second.isFixedLengthVector()) {
764 *
this, LT.second, ST->getRealVLen(),
766 if (VRegSplittingCost.
isValid())
767 return VRegSplittingCost;
772 if (Mask.size() >= 2) {
773 MVT EltTp = LT.second.getVectorElementType();
784 return 2 * LT.first * TLI->getLMULCost(LT.second);
786 if (Mask[0] == 0 || Mask[0] == 1) {
790 if (
equal(DeinterleaveMask, Mask))
791 return LT.first * getRISCVInstructionCost(RISCV::VNSRL_WI,
796 if (LT.second.getScalarSizeInBits() != 1 &&
799 unsigned NumSlides =
Log2_32(Mask.size() / SubVectorSize);
801 for (
unsigned I = 0;
I != NumSlides; ++
I) {
802 unsigned InsertIndex = SubVectorSize * (1 <<
I);
807 std::pair<InstructionCost, MVT> DestLT =
812 Cost += DestLT.first * TLI->getLMULCost(DestLT.second);
826 if (LT.first == 1 && (LT.second.getScalarSizeInBits() != 8 ||
827 LT.second.getVectorNumElements() <= 256)) {
832 getRISCVInstructionCost(RISCV::VRGATHER_VV, LT.second,
CostKind);
846 if (LT.first == 1 && (LT.second.getScalarSizeInBits() != 8 ||
847 LT.second.getVectorNumElements() <= 256)) {
848 auto &
C = SrcTy->getContext();
849 auto EC = SrcTy->getElementCount();
854 return 2 * IndexCost +
855 getRISCVInstructionCost({RISCV::VRGATHER_VV, RISCV::VRGATHER_VV},
874 if (!Mask.empty() && LT.first.isValid() && LT.first != 1 &&
902 SubLT.second.isValid() && SubLT.second.isFixedLengthVector()) {
903 if (std::optional<unsigned> VLen = ST->getRealVLen();
904 VLen && SubLT.second.getScalarSizeInBits() * Index % *VLen == 0 &&
905 SubLT.second.getSizeInBits() <= *VLen)
913 getRISCVInstructionCost(RISCV::VSLIDEDOWN_VI, LT.second,
CostKind);
920 getRISCVInstructionCost(RISCV::VSLIDEUP_VI, LT.second,
CostKind);
932 (1 + getRISCVInstructionCost({RISCV::VMV_S_X, RISCV::VMERGE_VVM},
939 if (IsLoad && LT.second.isVector() &&
941 LT.second.getVectorElementCount()))
945 Instruction::InsertElement);
946 if (LT.second.getScalarSizeInBits() == 1) {
954 (1 + getRISCVInstructionCost({RISCV::VMV_V_X, RISCV::VMSNE_VI},
967 (1 + getRISCVInstructionCost({RISCV::VMV_V_I, RISCV::VMERGE_VIM,
968 RISCV::VMV_X_S, RISCV::VMV_V_X,
977 getRISCVInstructionCost(RISCV::VMV_V_X, LT.second,
CostKind);
983 getRISCVInstructionCost(RISCV::VRGATHER_VI, LT.second,
CostKind);
989 unsigned Opcodes[2] = {RISCV::VSLIDEDOWN_VX, RISCV::VSLIDEUP_VX};
990 if (Index >= 0 && Index < 32)
991 Opcodes[0] = RISCV::VSLIDEDOWN_VI;
992 else if (Index < 0 && Index > -32)
993 Opcodes[1] = RISCV::VSLIDEUP_VI;
994 return LT.first * getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
998 if (!LT.second.isVector())
1004 if (SrcTy->getElementType()->isIntegerTy(1)) {
1016 MVT ContainerVT = LT.second;
1017 if (LT.second.isFixedLengthVector())
1018 ContainerVT = TLI->getContainerForFixedLengthVector(LT.second);
1020 if (ContainerVT.
bitsLE(M1VT)) {
1030 if (LT.second.isFixedLengthVector())
1032 LenCost =
isInt<5>(LT.second.getVectorNumElements() - 1) ? 0 : 1;
1033 unsigned Opcodes[] = {RISCV::VID_V, RISCV::VRSUB_VX, RISCV::VRGATHER_VV};
1034 if (LT.second.isFixedLengthVector() &&
1035 isInt<5>(LT.second.getVectorNumElements() - 1))
1036 Opcodes[1] = RISCV::VRSUB_VI;
1038 getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
1039 return LT.first * (LenCost + GatherCost);
1046 unsigned M1Opcodes[] = {RISCV::VID_V, RISCV::VRSUB_VX};
1048 getRISCVInstructionCost(M1Opcodes, M1VT,
CostKind) + 3;
1052 getRISCVInstructionCost({RISCV::VRGATHER_VV}, M1VT,
CostKind) * Ratio;
1054 getRISCVInstructionCost({RISCV::VSLIDEDOWN_VX}, LT.second,
CostKind);
1055 return FixedCost + LT.first * (GatherCost + SlideCost);
1089 Ty, DemandedElts, Insert, Extract,
CostKind);
1091 if (Insert && !Extract && LT.first.isValid() && LT.second.isVector()) {
1092 if (Ty->getScalarSizeInBits() == 1) {
1102 assert(LT.second.isFixedLengthVector());
1103 MVT ContainerVT = TLI->getContainerForFixedLengthVector(LT.second);
1107 getRISCVInstructionCost(RISCV::VSLIDE1DOWN_VX, LT.second,
CostKind);
1120 switch (MICA.
getID()) {
1121 case Intrinsic::vp_load_ff: {
1122 EVT DataTypeVT = TLI->getValueType(
DL, DataTy);
1123 if (!TLI->isLegalFirstFaultLoad(DataTypeVT, Alignment))
1130 case Intrinsic::experimental_vp_strided_load:
1131 case Intrinsic::experimental_vp_strided_store:
1133 case Intrinsic::masked_compressstore:
1134 case Intrinsic::masked_expandload:
1136 case Intrinsic::vp_scatter:
1137 case Intrinsic::vp_gather:
1138 case Intrinsic::masked_scatter:
1139 case Intrinsic::masked_gather:
1141 case Intrinsic::vp_load:
1142 case Intrinsic::vp_store:
1143 case Intrinsic::masked_load:
1144 case Intrinsic::masked_store:
1153 unsigned Opcode = MICA.
getID() == Intrinsic::masked_load ? Instruction::Load
1154 : Instruction::Store;
1169 bool UseMaskForCond,
bool UseMaskForGaps)
const {
1175 if (!UseMaskForGaps && Factor <= TLI->getMaxSupportedInterleaveFactor()) {
1179 if (LT.second.isVector()) {
1185 VTy->getElementCount().divideCoefficientBy(Factor));
1186 if (VTy->getElementCount().isKnownMultipleOf(Factor) &&
1187 TLI->isLegalInterleavedAccessType(SubVecTy, Factor, Alignment,
1192 if (ST->hasOptimizedSegmentLoadStore(Factor)) {
1193 unsigned VecSizeInBits =
1194 getEstimatedVLFor(VTy) * VTy->getScalarSizeInBits();
1195 unsigned VLENForTuning =
1197 unsigned DLENForTuning = VLENForTuning / ST->getDLenFactor();
1199 MVT SubVecVT = getTLI()->getValueType(
DL, SubVecTy).getSimpleVT();
1200 Cost += Factor * TLI->getLMULCost(SubVecVT);
1206 unsigned NumLoads = getEstimatedVLFor(VTy);
1222 if (UseMaskForGaps) {
1225 "Indices should not contain duplicate elements");
1226 unsigned NumOfFields = Indices.
size();
1227 bool IsTailGapOnly = NumOfFields > 1 && (NumOfFields == Indices.
back() + 1);
1228 if (IsTailGapOnly &&
1229 NumOfFields <= TLI->getMaxSupportedInterleaveFactor()) {
1231 if (LT.second.isVector() &&
1232 FVTy->getElementCount().isKnownMultipleOf(Factor)) {
1234 FVTy->getElementType(),
1235 FVTy->getElementCount().divideCoefficientBy(Factor));
1236 if (TLI->isLegalInterleavedAccessType(SubVecTy, NumOfFields, Alignment,
1239 unsigned NumAccesses = getEstimatedVLFor(FVTy);
1248 unsigned VF = FVTy->getNumElements() / Factor;
1255 if (Opcode == Instruction::Load) {
1257 for (
unsigned Index : Indices) {
1261 Mask.resize(VF * Factor, -1);
1265 Cost += ShuffleCost;
1283 UseMaskForCond, UseMaskForGaps);
1285 assert(Opcode == Instruction::Store &&
"Opcode must be a store");
1292 return MemCost + ShuffleCost;
1299 bool IsLoad = MICA.
getID() == Intrinsic::masked_gather ||
1300 MICA.
getID() == Intrinsic::vp_gather;
1301 unsigned Opcode = IsLoad ? Instruction::Load : Instruction::Store;
1307 if ((Opcode == Instruction::Load &&
1309 (Opcode == Instruction::Store &&
1317 unsigned NumLoads = getEstimatedVLFor(&VTy);
1324 unsigned Opcode = MICA.
getID() == Intrinsic::masked_expandload
1326 : Instruction::Store;
1330 bool IsLegal = (Opcode == Instruction::Store &&
1332 (Opcode == Instruction::Load &&
1356 if (Opcode == Instruction::Store)
1357 Opcodes.
append({RISCV::VCOMPRESS_VM});
1359 Opcodes.
append({RISCV::VSETIVLI, RISCV::VIOTA_M, RISCV::VRGATHER_VV});
1361 LT.first * getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
1380 unsigned NumLoads = getEstimatedVLFor(&VTy);
1391 for (
auto *Ty : Tys) {
1392 if (!Ty->isVectorTy())
1406 {Intrinsic::floor, MVT::f32, 9},
1407 {Intrinsic::floor, MVT::f64, 9},
1408 {Intrinsic::ceil, MVT::f32, 9},
1409 {Intrinsic::ceil, MVT::f64, 9},
1410 {Intrinsic::trunc, MVT::f32, 7},
1411 {Intrinsic::trunc, MVT::f64, 7},
1412 {Intrinsic::round, MVT::f32, 9},
1413 {Intrinsic::round, MVT::f64, 9},
1414 {Intrinsic::roundeven, MVT::f32, 9},
1415 {Intrinsic::roundeven, MVT::f64, 9},
1416 {Intrinsic::rint, MVT::f32, 7},
1417 {Intrinsic::rint, MVT::f64, 7},
1418 {Intrinsic::nearbyint, MVT::f32, 9},
1419 {Intrinsic::nearbyint, MVT::f64, 9},
1420 {Intrinsic::bswap, MVT::i16, 3},
1421 {Intrinsic::bswap, MVT::i32, 12},
1422 {Intrinsic::bswap, MVT::i64, 31},
1423 {Intrinsic::bitreverse, MVT::i8, 17},
1424 {Intrinsic::bitreverse, MVT::i16, 24},
1425 {Intrinsic::bitreverse, MVT::i32, 33},
1426 {Intrinsic::bitreverse, MVT::i64, 52},
1427 {Intrinsic::ctpop, MVT::i8, 12},
1428 {Intrinsic::ctpop, MVT::i16, 19},
1429 {Intrinsic::ctpop, MVT::i32, 20},
1430 {Intrinsic::ctpop, MVT::i64, 21},
1431 {Intrinsic::ctlz, MVT::i8, 19},
1432 {Intrinsic::ctlz, MVT::i16, 28},
1433 {Intrinsic::ctlz, MVT::i32, 31},
1434 {Intrinsic::ctlz, MVT::i64, 35},
1435 {Intrinsic::cttz, MVT::i8, 16},
1436 {Intrinsic::cttz, MVT::i16, 23},
1437 {Intrinsic::cttz, MVT::i32, 24},
1438 {Intrinsic::cttz, MVT::i64, 25},
1445 switch (ICA.
getID()) {
1446 case Intrinsic::lrint:
1447 case Intrinsic::llrint:
1448 case Intrinsic::lround:
1449 case Intrinsic::llround: {
1453 if (ST->hasVInstructions() && LT.second.isVector()) {
1455 unsigned SrcEltSz =
DL.getTypeSizeInBits(SrcTy->getScalarType());
1456 unsigned DstEltSz =
DL.getTypeSizeInBits(RetTy->getScalarType());
1457 if (LT.second.getVectorElementType() == MVT::bf16) {
1458 if (!ST->hasVInstructionsBF16Minimal())
1461 Ops = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFCVT_X_F_V};
1463 Ops = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFWCVT_X_F_V};
1464 }
else if (LT.second.getVectorElementType() == MVT::f16 &&
1465 !ST->hasVInstructionsF16()) {
1466 if (!ST->hasVInstructionsF16Minimal())
1469 Ops = {RISCV::VFWCVT_F_F_V, RISCV::VFCVT_X_F_V};
1471 Ops = {RISCV::VFWCVT_F_F_V, RISCV::VFWCVT_X_F_V};
1473 }
else if (SrcEltSz > DstEltSz) {
1474 Ops = {RISCV::VFNCVT_X_F_W};
1475 }
else if (SrcEltSz < DstEltSz) {
1476 Ops = {RISCV::VFWCVT_X_F_V};
1478 Ops = {RISCV::VFCVT_X_F_V};
1483 if (SrcEltSz > DstEltSz)
1484 return SrcLT.first *
1485 getRISCVInstructionCost(
Ops, SrcLT.second,
CostKind);
1486 return LT.first * getRISCVInstructionCost(
Ops, LT.second,
CostKind);
1490 case Intrinsic::ceil:
1491 case Intrinsic::floor:
1492 case Intrinsic::trunc:
1493 case Intrinsic::rint:
1494 case Intrinsic::round:
1495 case Intrinsic::roundeven: {
1498 if (!LT.second.isVector() && TLI->isOperationCustom(
ISD::FCEIL, LT.second))
1499 return LT.first * 8;
1502 case Intrinsic::umin:
1503 case Intrinsic::umax:
1504 case Intrinsic::smin:
1505 case Intrinsic::smax: {
1507 if (LT.second.isScalarInteger() && ST->hasStdExtZbb())
1510 if (ST->hasVInstructions() && LT.second.isVector()) {
1512 switch (ICA.
getID()) {
1513 case Intrinsic::umin:
1514 Op = RISCV::VMINU_VV;
1516 case Intrinsic::umax:
1517 Op = RISCV::VMAXU_VV;
1519 case Intrinsic::smin:
1520 Op = RISCV::VMIN_VV;
1522 case Intrinsic::smax:
1523 Op = RISCV::VMAX_VV;
1526 return LT.first * getRISCVInstructionCost(
Op, LT.second,
CostKind);
1530 case Intrinsic::sadd_sat:
1531 case Intrinsic::ssub_sat:
1532 case Intrinsic::uadd_sat:
1533 case Intrinsic::usub_sat: {
1535 if (ST->hasVInstructions() && LT.second.isVector()) {
1537 switch (ICA.
getID()) {
1538 case Intrinsic::sadd_sat:
1539 Op = RISCV::VSADD_VV;
1541 case Intrinsic::ssub_sat:
1542 Op = RISCV::VSSUB_VV;
1544 case Intrinsic::uadd_sat:
1545 Op = RISCV::VSADDU_VV;
1547 case Intrinsic::usub_sat:
1548 Op = RISCV::VSSUBU_VV;
1551 return LT.first * getRISCVInstructionCost(
Op, LT.second,
CostKind);
1555 case Intrinsic::fma:
1556 case Intrinsic::fmuladd: {
1559 if (ST->hasVInstructions() && LT.second.isVector())
1561 getRISCVInstructionCost(RISCV::VFMADD_VV, LT.second,
CostKind);
1564 case Intrinsic::fabs: {
1566 if (ST->hasVInstructions() && LT.second.isVector()) {
1572 if (LT.second.getVectorElementType() == MVT::bf16 ||
1573 (LT.second.getVectorElementType() == MVT::f16 &&
1574 !ST->hasVInstructionsF16()))
1575 return LT.first * getRISCVInstructionCost(RISCV::VAND_VX, LT.second,
1580 getRISCVInstructionCost(RISCV::VFSGNJX_VV, LT.second,
CostKind);
1584 case Intrinsic::sqrt: {
1586 if (ST->hasVInstructions() && LT.second.isVector()) {
1589 MVT ConvType = LT.second;
1590 MVT FsqrtType = LT.second;
1593 if (LT.second.getVectorElementType() == MVT::bf16) {
1594 if (LT.second == MVT::nxv32bf16) {
1595 ConvOp = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFWCVTBF16_F_F_V,
1596 RISCV::VFNCVTBF16_F_F_W, RISCV::VFNCVTBF16_F_F_W};
1597 FsqrtOp = {RISCV::VFSQRT_V, RISCV::VFSQRT_V};
1598 ConvType = MVT::nxv16f16;
1599 FsqrtType = MVT::nxv16f32;
1601 ConvOp = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFNCVTBF16_F_F_W};
1602 FsqrtOp = {RISCV::VFSQRT_V};
1603 FsqrtType = TLI->getTypeToPromoteTo(
ISD::FSQRT, FsqrtType);
1605 }
else if (LT.second.getVectorElementType() == MVT::f16 &&
1606 !ST->hasVInstructionsF16()) {
1607 if (LT.second == MVT::nxv32f16) {
1608 ConvOp = {RISCV::VFWCVT_F_F_V, RISCV::VFWCVT_F_F_V,
1609 RISCV::VFNCVT_F_F_W, RISCV::VFNCVT_F_F_W};
1610 FsqrtOp = {RISCV::VFSQRT_V, RISCV::VFSQRT_V};
1611 ConvType = MVT::nxv16f16;
1612 FsqrtType = MVT::nxv16f32;
1614 ConvOp = {RISCV::VFWCVT_F_F_V, RISCV::VFNCVT_F_F_W};
1615 FsqrtOp = {RISCV::VFSQRT_V};
1616 FsqrtType = TLI->getTypeToPromoteTo(
ISD::FSQRT, FsqrtType);
1619 FsqrtOp = {RISCV::VFSQRT_V};
1622 return LT.first * (getRISCVInstructionCost(FsqrtOp, FsqrtType,
CostKind) +
1623 getRISCVInstructionCost(ConvOp, ConvType,
CostKind));
1627 case Intrinsic::cttz:
1628 case Intrinsic::ctlz:
1629 case Intrinsic::ctpop: {
1631 if (ST->hasStdExtZvbb() && LT.second.isVector()) {
1633 switch (ICA.
getID()) {
1634 case Intrinsic::cttz:
1637 case Intrinsic::ctlz:
1640 case Intrinsic::ctpop:
1641 Op = RISCV::VCPOP_V;
1644 return LT.first * getRISCVInstructionCost(
Op, LT.second,
CostKind);
1648 case Intrinsic::abs: {
1650 if (ST->hasVInstructions() && LT.second.isVector()) {
1652 if (ST->hasStdExtZvabd())
1654 getRISCVInstructionCost({RISCV::VABD_VX}, LT.second,
CostKind);
1659 getRISCVInstructionCost({RISCV::VRSUB_VI, RISCV::VMAX_VV},
1664 case Intrinsic::fshl:
1665 case Intrinsic::fshr: {
1672 if ((ST->hasStdExtZbb() || ST->hasStdExtZbkb()) && RetTy->isIntegerTy() &&
1674 (RetTy->getIntegerBitWidth() == 32 ||
1675 RetTy->getIntegerBitWidth() == 64) &&
1676 RetTy->getIntegerBitWidth() <= ST->getXLen()) {
1681 case Intrinsic::clmul: {
1683 if (!LT.second.isVector() && ST->hasStdExtZvbc() && !ST->hasStdExtZbc() &&
1684 !ST->hasStdExtZbkc()) {
1687 if (!ST->is64Bit() || LT.second != MVT::i64)
1693 return LT.first * getRISCVInstructionCost(
1694 {RISCV::VMV_S_X, RISCV::VCLMUL_VX, RISCV::VMV_X_S},
1699 case Intrinsic::masked_udiv:
1702 case Intrinsic::masked_sdiv:
1705 case Intrinsic::masked_urem:
1708 case Intrinsic::masked_srem:
1711 case Intrinsic::get_active_lane_mask: {
1712 if (ST->hasVInstructions()) {
1721 getRISCVInstructionCost({RISCV::VSADDU_VX, RISCV::VMSLTU_VX},
1727 case Intrinsic::stepvector: {
1731 if (ST->hasVInstructions())
1732 return getRISCVInstructionCost(RISCV::VID_V, LT.second,
CostKind) +
1734 getRISCVInstructionCost(RISCV::VADD_VX, LT.second,
CostKind);
1735 return 1 + (LT.first - 1);
1737 case Intrinsic::vector_splice_left:
1738 case Intrinsic::vector_splice_right: {
1743 if (ST->hasVInstructions() && LT.second.isVector()) {
1745 getRISCVInstructionCost({RISCV::VSLIDEDOWN_VX, RISCV::VSLIDEUP_VX},
1750 case Intrinsic::experimental_cttz_elts: {
1751 if (!ST->hasVInstructions())
1758 if (LT.second.getVectorElementType() != MVT::i1)
1759 Cost += getRISCVInstructionCost(RISCV::VMSNE_VI, LT.second,
CostKind);
1761 Cost += getRISCVInstructionCost(RISCV::VFIRST_M, LT.second,
CostKind);
1773 return LT.first *
Cost;
1775 case Intrinsic::experimental_vp_splice: {
1783 case Intrinsic::vp_merge: {
1791 case Intrinsic::fptoui_sat:
1792 case Intrinsic::fptosi_sat: {
1794 bool IsSigned = ICA.
getID() == Intrinsic::fptosi_sat;
1799 if (!SrcTy->isVectorTy())
1802 if (!SrcLT.first.isValid() || !DstLT.first.isValid())
1819 case Intrinsic::experimental_vector_extract_last_active: {
1841 unsigned EltWidth = getTLI()->getBitWidthForCttzElements(
1842 TLI->getVectorIdxTy(
getDataLayout()), MaskTy->getElementCount(),
1843 true, &VScaleRange);
1844 EltWidth = std::max(EltWidth, MaskTy->getScalarSizeInBits());
1852 if (StepLT.first > 1)
1856 unsigned Opcodes[] = {RISCV::VID_V, RISCV::VREDMAXU_VS, RISCV::VMV_X_S};
1858 Cost += MaskLT.first *
1859 getRISCVInstructionCost(RISCV::VCPOP_M, MaskLT.second,
CostKind);
1861 Cost += StepLT.first *
1862 getRISCVInstructionCost(Opcodes, StepLT.second,
CostKind);
1866 Cost += ValLT.first *
1867 getRISCVInstructionCost({RISCV::VSLIDEDOWN_VI, RISCV::VMV_X_S},
1873 if (ST->hasVInstructions() && RetTy->isVectorTy()) {
1875 LT.second.isVector()) {
1876 MVT EltTy = LT.second.getVectorElementType();
1878 ICA.
getID(), EltTy))
1879 return LT.first * Entry->Cost;
1892 if (ST->hasVInstructions() && PtrTy->
isVectorTy())
1910 if (ST->hasStdExtP() &&
1918 if (!ST->hasVInstructions() || Src->getScalarSizeInBits() > ST->getELen() ||
1919 Dst->getScalarSizeInBits() > ST->getELen())
1922 int ISD = TLI->InstructionOpcodeToISD(Opcode);
1937 if (Src->getScalarSizeInBits() == 1) {
1942 return getRISCVInstructionCost(RISCV::VMV_V_I, DstLT.second,
CostKind) +
1943 DstLT.first * getRISCVInstructionCost(RISCV::VMERGE_VIM,
1949 if (Dst->getScalarSizeInBits() == 1) {
1955 return SrcLT.first *
1956 getRISCVInstructionCost({RISCV::VAND_VI, RISCV::VMSNE_VI},
1968 if (!SrcLT.second.isVector() || !DstLT.second.isVector() ||
1969 !SrcLT.first.isValid() || !DstLT.first.isValid() ||
1971 SrcLT.second.getSizeInBits()) ||
1973 DstLT.second.getSizeInBits()) ||
1974 SrcLT.first > 1 || DstLT.first > 1)
1978 assert((SrcLT.first == 1) && (DstLT.first == 1) &&
"Illegal type");
1980 int PowDiff = (int)
Log2_32(DstLT.second.getScalarSizeInBits()) -
1981 (int)
Log2_32(SrcLT.second.getScalarSizeInBits());
1985 if ((PowDiff < 1) || (PowDiff > 3))
1987 unsigned SExtOp[] = {RISCV::VSEXT_VF2, RISCV::VSEXT_VF4, RISCV::VSEXT_VF8};
1988 unsigned ZExtOp[] = {RISCV::VZEXT_VF2, RISCV::VZEXT_VF4, RISCV::VZEXT_VF8};
1991 return getRISCVInstructionCost(
Op, DstLT.second,
CostKind);
1997 unsigned SrcEltSize = SrcLT.second.getScalarSizeInBits();
1998 unsigned DstEltSize = DstLT.second.getScalarSizeInBits();
2002 : RISCV::VFNCVT_F_F_W;
2004 for (; SrcEltSize != DstEltSize;) {
2008 MVT DstMVT = DstLT.second.changeVectorElementType(ElementMVT);
2010 (DstEltSize > SrcEltSize) ? DstEltSize >> 1 : DstEltSize << 1;
2018 unsigned FCVT = IsSigned ? RISCV::VFCVT_RTZ_X_F_V : RISCV::VFCVT_RTZ_XU_F_V;
2020 IsSigned ? RISCV::VFWCVT_RTZ_X_F_V : RISCV::VFWCVT_RTZ_XU_F_V;
2022 IsSigned ? RISCV::VFNCVT_RTZ_X_F_W : RISCV::VFNCVT_RTZ_XU_F_W;
2023 unsigned SrcEltSize = Src->getScalarSizeInBits();
2024 unsigned DstEltSize = Dst->getScalarSizeInBits();
2026 if ((SrcEltSize == 16) &&
2027 (!ST->hasVInstructionsF16() || ((DstEltSize / 2) > SrcEltSize))) {
2033 std::pair<InstructionCost, MVT> VecF32LT =
2036 VecF32LT.first * getRISCVInstructionCost(RISCV::VFWCVT_F_F_V,
2041 if (DstEltSize == SrcEltSize)
2042 Cost += getRISCVInstructionCost(FCVT, DstLT.second,
CostKind);
2043 else if (DstEltSize > SrcEltSize)
2044 Cost += getRISCVInstructionCost(FWCVT, DstLT.second,
CostKind);
2049 MVT VecVT = DstLT.second.changeVectorElementType(ElementVT);
2050 Cost += getRISCVInstructionCost(FNCVT, VecVT,
CostKind);
2051 if ((SrcEltSize / 2) > DstEltSize) {
2062 unsigned FCVT = IsSigned ? RISCV::VFCVT_F_X_V : RISCV::VFCVT_F_XU_V;
2063 unsigned FWCVT = IsSigned ? RISCV::VFWCVT_F_X_V : RISCV::VFWCVT_F_XU_V;
2064 unsigned FNCVT = IsSigned ? RISCV::VFNCVT_F_X_W : RISCV::VFNCVT_F_XU_W;
2065 unsigned SrcEltSize = Src->getScalarSizeInBits();
2066 unsigned DstEltSize = Dst->getScalarSizeInBits();
2069 if ((DstEltSize == 16) &&
2070 (!ST->hasVInstructionsF16() || ((SrcEltSize / 2) > DstEltSize))) {
2076 std::pair<InstructionCost, MVT> VecF32LT =
2079 Cost += VecF32LT.first * getRISCVInstructionCost(RISCV::VFNCVT_F_F_W,
2084 if (DstEltSize == SrcEltSize)
2085 Cost += getRISCVInstructionCost(FCVT, DstLT.second,
CostKind);
2086 else if (DstEltSize > SrcEltSize) {
2087 if ((DstEltSize / 2) > SrcEltSize) {
2091 unsigned Op = IsSigned ? Instruction::SExt : Instruction::ZExt;
2094 Cost += getRISCVInstructionCost(FWCVT, DstLT.second,
CostKind);
2096 Cost += getRISCVInstructionCost(FNCVT, DstLT.second,
CostKind);
2103unsigned RISCVTTIImpl::getEstimatedVLFor(
VectorType *Ty)
const {
2105 const unsigned EltSize =
DL.getTypeSizeInBits(Ty->getElementType());
2106 const unsigned MinSize =
DL.getTypeSizeInBits(Ty).getKnownMinValue();
2121 if (Ty->getScalarSizeInBits() > ST->getELen())
2125 if (Ty->getElementType()->isIntegerTy(1)) {
2129 if (IID == Intrinsic::umax || IID == Intrinsic::smin)
2135 if (IID == Intrinsic::maximum || IID == Intrinsic::minimum) {
2139 case Intrinsic::maximum:
2141 Opcodes = {RISCV::VFREDMAX_VS, RISCV::VFMV_F_S};
2143 Opcodes = {RISCV::VMFNE_VV, RISCV::VCPOP_M, RISCV::VFREDMAX_VS,
2158 case Intrinsic::minimum:
2160 Opcodes = {RISCV::VFREDMIN_VS, RISCV::VFMV_F_S};
2162 Opcodes = {RISCV::VMFNE_VV, RISCV::VCPOP_M, RISCV::VFREDMIN_VS,
2168 const unsigned EltTyBits =
DL.getTypeSizeInBits(DstTy);
2177 return ExtraCost + getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2186 case Intrinsic::smax:
2187 SplitOp = RISCV::VMAX_VV;
2188 Opcodes = {RISCV::VREDMAX_VS, RISCV::VMV_X_S};
2190 case Intrinsic::smin:
2191 SplitOp = RISCV::VMIN_VV;
2192 Opcodes = {RISCV::VREDMIN_VS, RISCV::VMV_X_S};
2194 case Intrinsic::umax:
2195 SplitOp = RISCV::VMAXU_VV;
2196 Opcodes = {RISCV::VREDMAXU_VS, RISCV::VMV_X_S};
2198 case Intrinsic::umin:
2199 SplitOp = RISCV::VMINU_VV;
2200 Opcodes = {RISCV::VREDMINU_VS, RISCV::VMV_X_S};
2202 case Intrinsic::maxnum:
2203 SplitOp = RISCV::VFMAX_VV;
2204 Opcodes = {RISCV::VFREDMAX_VS, RISCV::VFMV_F_S};
2206 case Intrinsic::minnum:
2207 SplitOp = RISCV::VFMIN_VV;
2208 Opcodes = {RISCV::VFREDMIN_VS, RISCV::VFMV_F_S};
2213 (LT.first > 1) ? (LT.first - 1) *
2214 getRISCVInstructionCost(SplitOp, LT.second,
CostKind)
2216 return SplitCost + getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2221 std::optional<FastMathFlags> FMF,
2227 if (Ty->getScalarSizeInBits() > ST->getELen())
2230 int ISD = TLI->InstructionOpcodeToISD(Opcode);
2238 Type *ElementTy = Ty->getElementType();
2243 if (LT.second == MVT::v1i1)
2244 return getRISCVInstructionCost(RISCV::VFIRST_M, LT.second,
CostKind) +
2262 return ((LT.first > 2) ? (LT.first - 2) : 0) *
2263 getRISCVInstructionCost(RISCV::VMAND_MM, LT.second,
CostKind) +
2264 getRISCVInstructionCost(RISCV::VMNAND_MM, LT.second,
CostKind) +
2265 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind) +
2274 return (LT.first - 1) *
2275 getRISCVInstructionCost(RISCV::VMXOR_MM, LT.second,
CostKind) +
2276 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind) + 1;
2284 return (LT.first - 1) *
2285 getRISCVInstructionCost(RISCV::VMOR_MM, LT.second,
CostKind) +
2286 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind) +
2299 SplitOp = RISCV::VADD_VV;
2300 Opcodes = {RISCV::VMV_S_X, RISCV::VREDSUM_VS, RISCV::VMV_X_S};
2303 SplitOp = RISCV::VOR_VV;
2304 Opcodes = {RISCV::VREDOR_VS, RISCV::VMV_X_S};
2307 SplitOp = RISCV::VXOR_VV;
2308 Opcodes = {RISCV::VMV_S_X, RISCV::VREDXOR_VS, RISCV::VMV_X_S};
2311 SplitOp = RISCV::VAND_VV;
2312 Opcodes = {RISCV::VREDAND_VS, RISCV::VMV_X_S};
2316 if ((LT.second.getScalarType() == MVT::f16 && !ST->hasVInstructionsF16()) ||
2317 LT.second.getScalarType() == MVT::bf16)
2321 for (
unsigned i = 0; i < LT.first.getValue(); i++)
2324 return getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2326 SplitOp = RISCV::VFADD_VV;
2327 Opcodes = {RISCV::VFMV_S_F, RISCV::VFREDUSUM_VS, RISCV::VFMV_F_S};
2332 (LT.first > 1) ? (LT.first - 1) *
2333 getRISCVInstructionCost(SplitOp, LT.second,
CostKind)
2335 return SplitCost + getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2339 unsigned Opcode,
bool IsUnsigned,
Type *ResTy,
VectorType *ValTy,
2350 if (Opcode != Instruction::Add && Opcode != Instruction::FAdd)
2356 if (IsUnsigned && Opcode == Instruction::Add &&
2357 LT.second.isFixedLengthVectorOf(MVT::i1)) {
2361 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind);
2368 return (LT.first - 1) +
2375 assert(OpInfo.isConstant() &&
"non constant operand?");
2382 if (OpInfo.isUniform())
2388 return getConstantPoolLoadCost(Ty,
CostKind);
2397 EVT VT = TLI->getValueType(
DL, Src,
true);
2399 if (VT == MVT::Other ||
2405 if (Opcode == Instruction::Store && OpInfo.isConstant())
2420 if (Src->
isVectorTy() && LT.second.isVector() &&
2422 LT.second.getSizeInBits()))
2432 if (ST->hasVInstructions() && LT.second.isVector() &&
2434 BaseCost *= TLI->getLMULCost(LT.second);
2435 return Cost + BaseCost;
2444 Op1Info, Op2Info,
I);
2448 Op1Info, Op2Info,
I);
2453 Op1Info, Op2Info,
I);
2455 auto GetConstantMatCost =
2457 if (OpInfo.isUniform())
2462 return getConstantPoolLoadCost(ValTy,
CostKind);
2467 ConstantMatCost += GetConstantMatCost(Op1Info);
2469 ConstantMatCost += GetConstantMatCost(Op2Info);
2472 if (Opcode == Instruction::Select && LT.second.isVector()) {
2473 if (CondTy->isVectorTy()) {
2478 return ConstantMatCost +
2480 getRISCVInstructionCost(
2481 {RISCV::VMANDN_MM, RISCV::VMAND_MM, RISCV::VMOR_MM},
2485 return ConstantMatCost +
2486 LT.first * getRISCVInstructionCost(RISCV::VMERGE_VVM, LT.second,
2496 MVT InterimVT = LT.second.changeVectorElementType(MVT::i8);
2497 return ConstantMatCost +
2499 getRISCVInstructionCost({RISCV::VMV_V_X, RISCV::VMSNE_VI},
2501 LT.first * getRISCVInstructionCost(
2502 {RISCV::VMANDN_MM, RISCV::VMAND_MM, RISCV::VMOR_MM},
2509 return ConstantMatCost +
2510 LT.first * getRISCVInstructionCost(
2511 {RISCV::VMV_V_X, RISCV::VMSNE_VI, RISCV::VMERGE_VVM},
2515 if ((Opcode == Instruction::ICmp) && ValTy->
isVectorTy() &&
2519 return ConstantMatCost + LT.first * getRISCVInstructionCost(RISCV::VMSLT_VV,
2524 if ((Opcode == Instruction::FCmp) && ValTy->
isVectorTy() &&
2529 return ConstantMatCost +
2530 getRISCVInstructionCost(RISCV::VMXOR_MM, LT.second,
CostKind);
2540 Op1Info, Op2Info,
I);
2549 return ConstantMatCost +
2550 LT.first * getRISCVInstructionCost(
2551 {RISCV::VMFLT_VV, RISCV::VMFLT_VV, RISCV::VMOR_MM},
2558 return ConstantMatCost +
2560 getRISCVInstructionCost({RISCV::VMFLT_VV, RISCV::VMNAND_MM},
2569 return ConstantMatCost +
2571 getRISCVInstructionCost(RISCV::VMFLT_VV, LT.second,
CostKind);
2584 return match(U, m_Select(m_Specific(I), m_Value(), m_Value())) &&
2585 U->getType()->isIntegerTy() &&
2586 !isa<ConstantData>(U->getOperand(1)) &&
2587 !isa<ConstantData>(U->getOperand(2));
2595 Op1Info, Op2Info,
I);
2602 return Opcode == Instruction::PHI ? 0 : 1;
2619 if (Opcode != Instruction::ExtractElement &&
2620 Opcode != Instruction::InsertElement)
2628 if (!LT.second.isVector()) {
2638 auto NumElems = FixedVecTy->getNumElements();
2644 return Opcode == Instruction::ExtractElement
2645 ? StoreCost * NumElems + LoadCost
2646 : (StoreCost + LoadCost) * NumElems + StoreCost;
2650 if (LT.second.isScalableVector() && !LT.first.isValid())
2658 if (Opcode == Instruction::ExtractElement) {
2664 return ExtendCost + ExtractCost;
2674 return ExtendCost + InsertCost + TruncCost;
2681 if (LT.second.isFloatingPoint())
2682 MoveOpc = Opcode == Instruction::InsertElement ? RISCV::VFMV_S_F
2686 Opcode == Instruction::InsertElement ? RISCV::VMV_S_X : RISCV::VMV_X_S;
2688 getRISCVInstructionCost(MoveOpc, LT.second,
CostKind);
2690 InstructionCost SlideCost = Opcode == Instruction::InsertElement ? 2 : 1;
2695 if (LT.second.isFixedLengthVector()) {
2696 unsigned Width = LT.second.getVectorNumElements();
2697 Index = Index % Width;
2702 if (
auto VLEN = ST->getRealVLen()) {
2703 unsigned EltSize = LT.second.getScalarSizeInBits();
2704 unsigned M1Max = *VLEN / EltSize;
2705 Index = Index % M1Max;
2711 else if (Opcode == Instruction::InsertElement)
2719 ((Index == -1U) || (Index >= LT.second.getVectorMinNumElements() &&
2720 LT.second.isScalableVector()))) {
2722 Align VecAlign =
DL.getPrefTypeAlign(Val);
2723 Align SclAlign =
DL.getPrefTypeAlign(ScalarType);
2728 if (Opcode == Instruction::ExtractElement)
2764 Opcode == Instruction::InsertElement
2765 ? getRISCVInstructionCost({RISCV::VSLIDE1DOWN_VX,
2766 RISCV::VSLIDE1DOWN_VX,
2767 RISCV::VSLIDEUP_VX},
2769 : getRISCVInstructionCost({RISCV::VSLIDEDOWN_VX, RISCV::VMV_X_S,
2770 RISCV::VSRL_VX, RISCV::VMV_X_S},
2773 return BaseCost + SlideCost;
2779 unsigned Index)
const {
2788 assert(Index < EC.getKnownMinValue() &&
"Unexpected reverse index");
2790 EC.getKnownMinValue() - 1 - Index,
nullptr,
2799std::optional<InstructionCost>
2805 if ((Opcode == Instruction::UDiv || Opcode == Instruction::URem) &&
2807 if (Opcode == Instruction::UDiv)
2814 return std::nullopt;
2836 if (std::optional<InstructionCost> CombinedCost =
2838 Op2Info, Args, CxtI))
2839 return *CombinedCost;
2843 unsigned ISDOpcode = TLI->InstructionOpcodeToISD(Opcode);
2846 if (!LT.second.isVector()) {
2856 if (TLI->isOperationLegalOrPromote(ISDOpcode, LT.second))
2857 if (
const auto *Entry =
CostTableLookup(DivTbl, ISDOpcode, LT.second))
2858 return Entry->Cost * LT.first;
2867 if ((LT.second.getVectorElementType() == MVT::f16 ||
2868 LT.second.getVectorElementType() == MVT::bf16) &&
2869 TLI->getOperationAction(ISDOpcode, LT.second) ==
2871 MVT PromotedVT = TLI->getTypeToPromoteTo(ISDOpcode, LT.second);
2875 CastCost += LT.first * Args.size() *
2883 LT.second = PromotedVT;
2886 auto getConstantMatCost =
2896 return getConstantPoolLoadCost(Ty,
CostKind);
2902 ConstantMatCost += getConstantMatCost(0, Op1Info);
2904 ConstantMatCost += getConstantMatCost(1, Op2Info);
2907 switch (ISDOpcode) {
2910 Op = RISCV::VADD_VV;
2915 Op = RISCV::VSLL_VV;
2920 Op = (Ty->getScalarSizeInBits() == 1) ? RISCV::VMAND_MM : RISCV::VAND_VV;
2925 Op = RISCV::VMUL_VV;
2929 Op = RISCV::VDIV_VV;
2933 Op = RISCV::VREM_VV;
2937 Op = RISCV::VFADD_VV;
2940 Op = RISCV::VFMUL_VV;
2943 Op = RISCV::VFDIV_VV;
2946 Op = RISCV::VFSGNJN_VV;
2951 return CastCost + ConstantMatCost +
2960 if (Ty->isFPOrFPVectorTy())
2962 return CastCost + ConstantMatCost + LT.first *
InstrCost;
2985 if (Info.isSameBase() && V !=
Base) {
2986 if (
GEP->hasAllConstantIndices())
2992 unsigned Stride =
DL.getTypeStoreSize(AccessTy);
2993 if (Info.isUnitStride() &&
2999 GEP->getType()->getPointerAddressSpace()))
3002 {TTI::OK_AnyValue, TTI::OP_None},
3003 {TTI::OK_AnyValue, TTI::OP_None}, {});
3020 if (ST->enableDefaultUnroll())
3030 if (L->getHeader()->getParent()->hasOptSize())
3034 L->getExitingBlocks(ExitingBlocks);
3036 <<
"Blocks: " << L->getNumBlocks() <<
"\n"
3037 <<
"Exit blocks: " << ExitingBlocks.
size() <<
"\n");
3041 if (ExitingBlocks.
size() > 2)
3046 if (L->getNumBlocks() > 4)
3054 for (
auto *BB : L->getBlocks()) {
3055 for (
auto &
I : *BB) {
3059 if (IsVectorized && (
I.getType()->isVectorTy() ||
3061 return V->getType()->isVectorTy();
3100 bool HasMask =
false;
3103 bool IsWrite) -> int64_t {
3104 if (
auto *TarExtTy =
3106 return TarExtTy->getIntParameter(0);
3112 case Intrinsic::riscv_vle_mask:
3113 case Intrinsic::riscv_vse_mask:
3114 case Intrinsic::riscv_vlseg2_mask:
3115 case Intrinsic::riscv_vlseg3_mask:
3116 case Intrinsic::riscv_vlseg4_mask:
3117 case Intrinsic::riscv_vlseg5_mask:
3118 case Intrinsic::riscv_vlseg6_mask:
3119 case Intrinsic::riscv_vlseg7_mask:
3120 case Intrinsic::riscv_vlseg8_mask:
3121 case Intrinsic::riscv_vsseg2_mask:
3122 case Intrinsic::riscv_vsseg3_mask:
3123 case Intrinsic::riscv_vsseg4_mask:
3124 case Intrinsic::riscv_vsseg5_mask:
3125 case Intrinsic::riscv_vsseg6_mask:
3126 case Intrinsic::riscv_vsseg7_mask:
3127 case Intrinsic::riscv_vsseg8_mask:
3130 case Intrinsic::riscv_vle:
3131 case Intrinsic::riscv_vse:
3132 case Intrinsic::riscv_vlseg2:
3133 case Intrinsic::riscv_vlseg3:
3134 case Intrinsic::riscv_vlseg4:
3135 case Intrinsic::riscv_vlseg5:
3136 case Intrinsic::riscv_vlseg6:
3137 case Intrinsic::riscv_vlseg7:
3138 case Intrinsic::riscv_vlseg8:
3139 case Intrinsic::riscv_vsseg2:
3140 case Intrinsic::riscv_vsseg3:
3141 case Intrinsic::riscv_vsseg4:
3142 case Intrinsic::riscv_vsseg5:
3143 case Intrinsic::riscv_vsseg6:
3144 case Intrinsic::riscv_vsseg7:
3145 case Intrinsic::riscv_vsseg8: {
3162 Ty = TarExtTy->getTypeParameter(0U);
3167 const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
3168 unsigned VLIndex = RVVIInfo->VLOperand;
3169 unsigned PtrOperandNo = VLIndex - 1 - HasMask;
3177 unsigned SegNum = getSegNum(Inst, PtrOperandNo, IsWrite);
3180 unsigned ElemSize = Ty->getScalarSizeInBits();
3184 Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty,
3185 Alignment, Mask, EVL);
3188 case Intrinsic::riscv_vlse_mask:
3189 case Intrinsic::riscv_vsse_mask:
3190 case Intrinsic::riscv_vlsseg2_mask:
3191 case Intrinsic::riscv_vlsseg3_mask:
3192 case Intrinsic::riscv_vlsseg4_mask:
3193 case Intrinsic::riscv_vlsseg5_mask:
3194 case Intrinsic::riscv_vlsseg6_mask:
3195 case Intrinsic::riscv_vlsseg7_mask:
3196 case Intrinsic::riscv_vlsseg8_mask:
3197 case Intrinsic::riscv_vssseg2_mask:
3198 case Intrinsic::riscv_vssseg3_mask:
3199 case Intrinsic::riscv_vssseg4_mask:
3200 case Intrinsic::riscv_vssseg5_mask:
3201 case Intrinsic::riscv_vssseg6_mask:
3202 case Intrinsic::riscv_vssseg7_mask:
3203 case Intrinsic::riscv_vssseg8_mask:
3206 case Intrinsic::riscv_vlse:
3207 case Intrinsic::riscv_vsse:
3208 case Intrinsic::riscv_vlsseg2:
3209 case Intrinsic::riscv_vlsseg3:
3210 case Intrinsic::riscv_vlsseg4:
3211 case Intrinsic::riscv_vlsseg5:
3212 case Intrinsic::riscv_vlsseg6:
3213 case Intrinsic::riscv_vlsseg7:
3214 case Intrinsic::riscv_vlsseg8:
3215 case Intrinsic::riscv_vssseg2:
3216 case Intrinsic::riscv_vssseg3:
3217 case Intrinsic::riscv_vssseg4:
3218 case Intrinsic::riscv_vssseg5:
3219 case Intrinsic::riscv_vssseg6:
3220 case Intrinsic::riscv_vssseg7:
3221 case Intrinsic::riscv_vssseg8: {
3238 Ty = TarExtTy->getTypeParameter(0U);
3243 const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
3244 unsigned VLIndex = RVVIInfo->VLOperand;
3245 unsigned PtrOperandNo = VLIndex - 2 - HasMask;
3254 unsigned PointerAlign = Alignment.valueOrOne().value();
3257 Alignment =
Align(1);
3264 unsigned SegNum = getSegNum(Inst, PtrOperandNo, IsWrite);
3267 unsigned ElemSize = Ty->getScalarSizeInBits();
3271 Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty,
3272 Alignment, Mask, EVL, Stride);
3275 case Intrinsic::riscv_vloxei_mask:
3276 case Intrinsic::riscv_vluxei_mask:
3277 case Intrinsic::riscv_vsoxei_mask:
3278 case Intrinsic::riscv_vsuxei_mask:
3279 case Intrinsic::riscv_vloxseg2_mask:
3280 case Intrinsic::riscv_vloxseg3_mask:
3281 case Intrinsic::riscv_vloxseg4_mask:
3282 case Intrinsic::riscv_vloxseg5_mask:
3283 case Intrinsic::riscv_vloxseg6_mask:
3284 case Intrinsic::riscv_vloxseg7_mask:
3285 case Intrinsic::riscv_vloxseg8_mask:
3286 case Intrinsic::riscv_vluxseg2_mask:
3287 case Intrinsic::riscv_vluxseg3_mask:
3288 case Intrinsic::riscv_vluxseg4_mask:
3289 case Intrinsic::riscv_vluxseg5_mask:
3290 case Intrinsic::riscv_vluxseg6_mask:
3291 case Intrinsic::riscv_vluxseg7_mask:
3292 case Intrinsic::riscv_vluxseg8_mask:
3293 case Intrinsic::riscv_vsoxseg2_mask:
3294 case Intrinsic::riscv_vsoxseg3_mask:
3295 case Intrinsic::riscv_vsoxseg4_mask:
3296 case Intrinsic::riscv_vsoxseg5_mask:
3297 case Intrinsic::riscv_vsoxseg6_mask:
3298 case Intrinsic::riscv_vsoxseg7_mask:
3299 case Intrinsic::riscv_vsoxseg8_mask:
3300 case Intrinsic::riscv_vsuxseg2_mask:
3301 case Intrinsic::riscv_vsuxseg3_mask:
3302 case Intrinsic::riscv_vsuxseg4_mask:
3303 case Intrinsic::riscv_vsuxseg5_mask:
3304 case Intrinsic::riscv_vsuxseg6_mask:
3305 case Intrinsic::riscv_vsuxseg7_mask:
3306 case Intrinsic::riscv_vsuxseg8_mask:
3309 case Intrinsic::riscv_vloxei:
3310 case Intrinsic::riscv_vluxei:
3311 case Intrinsic::riscv_vsoxei:
3312 case Intrinsic::riscv_vsuxei:
3313 case Intrinsic::riscv_vloxseg2:
3314 case Intrinsic::riscv_vloxseg3:
3315 case Intrinsic::riscv_vloxseg4:
3316 case Intrinsic::riscv_vloxseg5:
3317 case Intrinsic::riscv_vloxseg6:
3318 case Intrinsic::riscv_vloxseg7:
3319 case Intrinsic::riscv_vloxseg8:
3320 case Intrinsic::riscv_vluxseg2:
3321 case Intrinsic::riscv_vluxseg3:
3322 case Intrinsic::riscv_vluxseg4:
3323 case Intrinsic::riscv_vluxseg5:
3324 case Intrinsic::riscv_vluxseg6:
3325 case Intrinsic::riscv_vluxseg7:
3326 case Intrinsic::riscv_vluxseg8:
3327 case Intrinsic::riscv_vsoxseg2:
3328 case Intrinsic::riscv_vsoxseg3:
3329 case Intrinsic::riscv_vsoxseg4:
3330 case Intrinsic::riscv_vsoxseg5:
3331 case Intrinsic::riscv_vsoxseg6:
3332 case Intrinsic::riscv_vsoxseg7:
3333 case Intrinsic::riscv_vsoxseg8:
3334 case Intrinsic::riscv_vsuxseg2:
3335 case Intrinsic::riscv_vsuxseg3:
3336 case Intrinsic::riscv_vsuxseg4:
3337 case Intrinsic::riscv_vsuxseg5:
3338 case Intrinsic::riscv_vsuxseg6:
3339 case Intrinsic::riscv_vsuxseg7:
3340 case Intrinsic::riscv_vsuxseg8: {
3357 Ty = TarExtTy->getTypeParameter(0U);
3362 const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
3363 unsigned VLIndex = RVVIInfo->VLOperand;
3364 unsigned PtrOperandNo = VLIndex - 2 - HasMask;
3377 unsigned SegNum = getSegNum(Inst, PtrOperandNo, IsWrite);
3380 unsigned ElemSize = Ty->getScalarSizeInBits();
3385 Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty,
3386 Align(1), Mask, EVL,
3395 if (Ty->isVectorTy()) {
3398 if ((EltTy->
isHalfTy() && !ST->hasVInstructionsF16()) ||
3404 if (
Size.isScalable() && ST->hasVInstructions())
3407 if (ST->useRVVForFixedLengthVectors())
3427 return std::max<unsigned>(1U, RegWidth.
getFixedValue() / ElemWidth);
3435 return ST->enableUnalignedVectorMem();
3441 if (ST->hasVendorXCVmem() && !ST->is64Bit())
3463 Align Alignment)
const {
3465 if (!VTy || VTy->isScalableTy())
3473 if (VTy->getElementType()->isIntegerTy(8))
3474 if (VTy->getElementCount().getFixedValue() > 256)
3475 return VTy->getPrimitiveSizeInBits() / ST->getRealMinVLen() <
3476 ST->getMaxLMULForFixedLengthVectors();
3481 Align Alignment)
const {
3483 if (!VTy || VTy->isScalableTy())
3494 if (!ST->hasVInstructions() || !ST->hasOptimizedZeroStrideLoad())
3497 return TLI->isLegalElementTypeForRVV(TLI->getValueType(
DL, ElementTy));
3506 const Instruction &
I,
bool &AllowPromotionWithoutCommonHeader)
const {
3507 bool Considerable =
false;
3508 AllowPromotionWithoutCommonHeader =
false;
3511 Type *ConsideredSExtType =
3513 if (
I.getType() != ConsideredSExtType)
3517 for (
const User *U :
I.users()) {
3519 Considerable =
true;
3523 if (GEPInst->getNumOperands() > 2) {
3524 AllowPromotionWithoutCommonHeader =
true;
3529 return Considerable;
3534 case Instruction::Add:
3535 case Instruction::Sub:
3536 case Instruction::Mul:
3537 case Instruction::And:
3538 case Instruction::Or:
3539 case Instruction::Xor:
3540 case Instruction::FAdd:
3541 case Instruction::FSub:
3542 case Instruction::FMul:
3543 case Instruction::FDiv:
3544 case Instruction::ICmp:
3545 case Instruction::FCmp:
3547 case Instruction::Shl:
3548 case Instruction::LShr:
3549 case Instruction::AShr:
3550 case Instruction::UDiv:
3551 case Instruction::SDiv:
3552 case Instruction::URem:
3553 case Instruction::SRem:
3554 case Instruction::Select:
3555 return Operand == 1;
3562 if (!
I->getType()->isVectorTy() || !ST->hasVInstructions())
3572 switch (
II->getIntrinsicID()) {
3573 case Intrinsic::fma:
3574 case Intrinsic::fmuladd:
3575 return Operand == 0 || Operand == 1;
3576 case Intrinsic::vp_udiv:
3577 case Intrinsic::vp_sdiv:
3578 case Intrinsic::vp_urem:
3579 case Intrinsic::vp_srem:
3580 case Intrinsic::ssub_sat:
3581 case Intrinsic::usub_sat:
3582 return Operand == 1;
3584 case Intrinsic::smin:
3585 case Intrinsic::umin:
3586 case Intrinsic::smax:
3587 case Intrinsic::umax:
3588 case Intrinsic::sadd_sat:
3589 case Intrinsic::uadd_sat:
3590 return Operand == 0 || Operand == 1;
3603 if (
I->isBitwiseLogicOp()) {
3604 if (!
I->getType()->isVectorTy()) {
3605 if (ST->hasStdExtZbb() || ST->hasStdExtZbkb()) {
3606 for (
auto &
Op :
I->operands()) {
3614 }
else if (
I->getOpcode() == Instruction::And && ST->hasStdExtZvkb()) {
3615 for (
auto &
Op :
I->operands()) {
3627 Ops.push_back(&Not);
3628 Ops.push_back(&InsertElt);
3636 if (!
I->getType()->isVectorTy() || !ST->hasVInstructions())
3644 if (!ST->sinkSplatOperands())
3647 for (
auto OpIdx :
enumerate(
I->operands())) {
3667 for (
Use &U :
Op->uses()) {
3674 Use *InsertEltUse = &
Op->getOperandUse(0);
3677 Ops.push_back(&InsertElt->getOperandUse(1));
3678 Ops.push_back(InsertEltUse);
3679 Ops.push_back(&OpIdx.value());
3688 if (!ST->hasStdExtZbb() && !ST->hasStdExtZbkb() && !IsZeroCmp)
3691 Options.AllowOverlappingLoads =
true;
3692 Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize);
3694 if (ST->is64Bit()) {
3695 Options.LoadSizes = {8, 4, 2, 1};
3696 Options.AllowedTailExpansions = {3, 5, 6};
3698 Options.LoadSizes = {4, 2, 1};
3699 Options.AllowedTailExpansions = {3};
3702 if (IsZeroCmp && ST->hasVInstructions()) {
3703 unsigned VLenB = ST->getRealMinVLen() / 8;
3706 unsigned MinSize = ST->getXLen() / 8 + 1;
3707 unsigned MaxSize = VLenB * ST->getMaxLMULForFixedLengthVectors();
3721 if (
I->getOpcode() == Instruction::Or &&
3725 if (
I->getOpcode() == Instruction::Add ||
3726 I->getOpcode() == Instruction::Sub)
3744std::optional<Instruction *>
3750 if (
is_contained({Intrinsic::riscv_vsetvli, Intrinsic::riscv_vsetvlimax},
3751 II.getIntrinsicID())) {
3754 if (!ST->hasVInstructions())
3757 bool HasAVL =
II.getIntrinsicID() == Intrinsic::riscv_vsetvli;
3758 unsigned Offset = HasAVL ? 1 : 0;
3759 unsigned BitWidth =
II.getType()->getIntegerBitWidth();
3784 Value *AVL =
II.getArgOperand(0);
3813 II.getRange().value_or(ConstantRange::getFull(
BitWidth));
3815 if (NewRange != OldRange) {
3816 II.addRangeRetAttr(NewRange);
3826 if (
II.user_empty())
3831 const APInt *Scalar;
3836 return U->getType() == TargetVecTy && match(U, m_BitCast(m_Value()));
3840 unsigned TargetEltBW =
DL.getTypeSizeInBits(TargetVecTy->getElementType());
3841 unsigned SourceEltBW =
DL.getTypeSizeInBits(SourceVecTy->getElementType());
3842 if (TargetEltBW % SourceEltBW)
3844 unsigned TargetScale = TargetEltBW / SourceEltBW;
3845 if (VL % TargetScale || TargetScale == 1)
3847 Type *VLTy =
II.getOperand(2)->getType();
3848 ElementCount SourceEC = SourceVecTy->getElementCount();
3849 unsigned NewEltBW = SourceEltBW * TargetScale;
3851 !
DL.fitsInLegalInteger(NewEltBW))
3854 if (!TLI->isLegalElementTypeForRVV(TLI->getValueType(
DL, NewEltTy)))
3858 assert(SourceVecTy->canLosslesslyBitCastTo(RetTy) &&
3859 "Lossless bitcast between types expected");
3865 RetTy, Intrinsic::riscv_vmv_v_x,
3866 {PoisonValue::get(RetTy), ConstantInt::get(NewEltTy, NewScalar),
3867 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[]
uint64_t IntrinsicInst * II
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
TTI::ShuffleKind improveShuffleKindFromMask(TTI::ShuffleKind Kind, ArrayRef< int > Mask, VectorType *SrcTy, int &Index, VectorType *&SubTy) const
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace, Instruction *I=nullptr, int64_t ScalableOffset=0) const override
InstructionCost getScalarizationOverhead(VectorType *InTy, const APInt &DemandedElts, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
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
InstructionCost getGEPCost(Type *PointeeType, const Value *Ptr, ArrayRef< const Value * > Operands, TTI::TargetCostKind CostKind, Type *AccessType) const override
unsigned getRegUsageForType(Type *Ty) const override
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, TTI::TargetCostKind CostKind, ArrayRef< int > Mask, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) 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
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ 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
@ ICMP_ULT
unsigned less than
@ 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
@ ICMP_ULE
unsigned less or 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.
LLVM_ABI ConstantRange umin(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned minimum of a value in ...
LLVM_ABI APInt getUnsignedMin() const
Return the smallest unsigned value contained in the ConstantRange.
LLVM_ABI bool icmp(CmpInst::Predicate Pred, const ConstantRange &Other) const
Does the predicate Pred hold between ranges this and Other?
LLVM_ABI ConstantRange umax(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned maximum of a value in ...
static LLVM_ABI ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred, const ConstantRange &Other)
Produce the smallest range such that all values that may satisfy the given predicate with any value c...
LLVM_ABI ConstantRange multiply(const ConstantRange &Other, unsigned NoWrapKind=0) const
Return a new range representing the possible values resulting from a multiplication of a value in thi...
LLVM_ABI APInt getUnsignedMax() const
Return the largest unsigned value contained in the ConstantRange.
LLVM_ABI ConstantRange intersectWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the intersection of this range with another range.
LLVM_ABI ConstantRange udiv(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned division of a value in...
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.
const SimplifyQuery & getSimplifyQuery() const
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:
user_iterator user_begin()
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
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, TTI::TargetCostKind CostKind, ArrayRef< int > Mask, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
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...
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 getPointersChainCost(ArrayRef< const Value * > Ptrs, const Value *Base, const TTI::PointersChainInfo &Info, Type *AccessTy, const TTI::TargetCostKind CostKind) const override
unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) 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.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
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)
LLVM_ABI bool isScalableTy() const
Return true if this is a type whose size is a known multiple of vscale.
bool isIntegerTy() const
True if this is an instance of IntegerType.
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
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.
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 bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr bool isFixed() const
Returns true if the quantity is not scaled by vscale.
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.
LLVM_ABI APInt RoundingUDiv(const APInt &A, const APInt &B, APInt::Rounding RM)
Return A unsign-divided by B, rounded by the given rounding mode.
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 unsigned decodeVSEW(unsigned VSEW)
LLVM_ABI std::pair< unsigned, bool > decodeVLMUL(VLMUL VLMul)
LLVM_ABI unsigned getSEWLMULRatio(unsigned SEW, VLMUL VLMul)
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.
LLVM_ABI ConstantRange computeConstantRangeIncludingKnownBits(const WithCache< const Value * > &V, bool ForSigned, const SimplifyQuery &SQ)
Combine constant ranges from computeConstantRange() and computeKnownBits().
DWARFExpression::Operation Op
OutputIt copy(R &&Range, OutputIt Out)
constexpr unsigned BitWidth
CostTblEntryT< uint16_t > CostTblEntry
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
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.
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.
Information about a load/store intrinsic defined by the target.
SimplifyQuery getWithInstruction(const Instruction *I) const