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)
360 if (!ST->hasStdExtZvdot4a8i() || ST->getELen() < 64 ||
361 Opcode != Instruction::Add || !BinOp || *BinOp != Instruction::Mul ||
362 InputTypeA != InputTypeB || !InputTypeA->
isIntegerTy(8) ||
378 getRISCVInstructionCost(RISCV::VDOT4A_VV, DotLT.second,
CostKind);
387 std::pair<InstructionCost, MVT> AccLT =
395 bool WidenFirst =
false;
396 if (VF.
isScalable() && AccLT.second.isScalableVector()) {
397 MVT NarrowMVT = AccLT.second.changeVectorElementType(MVT::i32);
410 WideLT.first * getRISCVInstructionCost(RISCV::VSEXT_VF2,
413 getRISCVInstructionCost(RISCV::VADD_VV, AccLT.second,
CostKind);
417 std::pair<InstructionCost, MVT> RedLT =
419 Cost += RedLT.first * getRISCVInstructionCost(RISCV::VADD_VV,
421 AccLT.first * getRISCVInstructionCost(RISCV::VWADD_WV,
425 Cost += DotLT.first * getRISCVInstructionCost(RISCV::VSLIDEDOWN_VI,
437 switch (
II->getIntrinsicID()) {
441 case Intrinsic::vector_reduce_mul:
442 case Intrinsic::vector_reduce_fmul:
448 if (ST->hasVInstructions())
454 if (ST->hasVInstructions())
455 if (
unsigned MinVLen = ST->getRealMinVLen();
470 ST->useRVVForFixedLengthVectors() ? LMUL * ST->getRealMinVLen() : 0);
473 (ST->hasVInstructions() &&
496 return (ST->hasAUIPCADDIFusion() && ST->hasLUIADDIFusion()) ? 1 : 2;
502RISCVTTIImpl::getConstantPoolLoadCost(
Type *Ty,
507 return getStaticDataAddrGenerationCost(
CostKind) +
513 unsigned Size = Mask.size();
516 for (
unsigned I = 0;
I !=
Size; ++
I) {
517 if (
static_cast<unsigned>(Mask[
I]) ==
I)
523 for (
unsigned J =
I + 1; J !=
Size; ++J)
525 if (
static_cast<unsigned>(Mask[J]) != J %
I)
553 "Expected fixed vector type and non-empty mask");
556 unsigned NumOfDests =
divideCeil(Mask.size(), LegalNumElts);
560 if (NumOfDests <= 1 ||
562 Tp->getElementType()->getPrimitiveSizeInBits() ||
563 LegalNumElts >= Tp->getElementCount().getFixedValue())
566 unsigned VecTySize =
TTI.getDataLayout().getTypeStoreSize(Tp);
569 unsigned NumOfSrcs =
divideCeil(VecTySize, LegalVTSize);
573 unsigned NormalizedVF = LegalNumElts * std::max(NumOfSrcs, NumOfDests);
574 unsigned NumOfSrcRegs = NormalizedVF / LegalNumElts;
575 unsigned NumOfDestRegs = NormalizedVF / LegalNumElts;
577 assert(NormalizedVF >= Mask.size() &&
578 "Normalized mask expected to be not shorter than original mask.");
583 NormalizedMask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, []() {},
584 [&](
ArrayRef<int> RegMask,
unsigned SrcReg,
unsigned DestReg) {
587 if (!ReusedSingleSrcShuffles.
insert(std::make_pair(RegMask, SrcReg))
590 Cost +=
TTI.getShuffleCost(
593 SingleOpTy,
CostKind, RegMask, 0,
nullptr);
595 [&](
ArrayRef<int> RegMask,
unsigned Idx1,
unsigned Idx2,
bool NewReg) {
596 Cost +=
TTI.getShuffleCost(
599 SingleOpTy,
CostKind, RegMask, 0,
nullptr);
622 if (!VLen || Mask.empty())
626 LegalVT =
TTI.getTypeLegalizationCost(
632 if (NumOfDests <= 1 ||
634 Tp->getElementType()->getPrimitiveSizeInBits() ||
638 unsigned VecTySize =
TTI.getDataLayout().getTypeStoreSize(Tp);
641 unsigned NumOfSrcs =
divideCeil(VecTySize, LegalVTSize);
647 unsigned NormalizedVF =
652 assert(NormalizedVF >= Mask.size() &&
653 "Normalized mask expected to be not shorter than original mask.");
659 NormalizedMask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, []() {},
660 [&](
ArrayRef<int> RegMask,
unsigned SrcReg,
unsigned DestReg) {
663 if (!ReusedSingleSrcShuffles.
insert(std::make_pair(RegMask, SrcReg))
668 SingleOpTy,
CostKind, RegMask, 0,
nullptr);
670 [&](
ArrayRef<int> RegMask,
unsigned Idx1,
unsigned Idx2,
bool NewReg) {
672 SingleOpTy,
CostKind, RegMask, 0,
nullptr);
679 if ((NumOfDestRegs > 2 && NumShuffles <=
static_cast<int>(NumOfDestRegs)) ||
680 (NumOfDestRegs <= 2 && NumShuffles < 4))
695 if (!
LT.second.isFixedLengthVector())
703 auto GetSlideOpcode = [&](
int SlideAmt) {
705 bool IsVI =
isUInt<5>(std::abs(SlideAmt));
707 return IsVI ? RISCV::VSLIDEDOWN_VI : RISCV::VSLIDEDOWN_VX;
708 return IsVI ? RISCV::VSLIDEUP_VI : RISCV::VSLIDEUP_VX;
711 std::array<std::pair<int, int>, 2> SrcInfo;
715 if (SrcInfo[1].second == 0)
719 if (SrcInfo[0].second != 0) {
720 unsigned Opcode = GetSlideOpcode(SrcInfo[0].second);
721 FirstSlideCost = getRISCVInstructionCost(Opcode,
LT.second,
CostKind);
724 if (SrcInfo[1].first == -1)
725 return FirstSlideCost;
728 if (SrcInfo[1].second != 0) {
729 unsigned Opcode = GetSlideOpcode(SrcInfo[1].second);
730 SecondSlideCost = getRISCVInstructionCost(Opcode,
LT.second,
CostKind);
733 getRISCVInstructionCost(RISCV::VMERGE_VVM,
LT.second,
CostKind);
740 return FirstSlideCost + SecondSlideCost + MaskCost;
751 "Expected the Mask to match the return size if given");
753 "Expected the same scalar types");
769 FVTp && ST->hasVInstructions() && LT.second.isFixedLengthVector()) {
771 *
this, LT.second, ST->getRealVLen(),
773 if (VRegSplittingCost.
isValid())
774 return VRegSplittingCost;
779 if (Mask.size() >= 2) {
780 MVT EltTp = LT.second.getVectorElementType();
791 return 2 * LT.first * TLI->getLMULCost(LT.second);
793 if (Mask[0] == 0 || Mask[0] == 1) {
797 if (
equal(DeinterleaveMask, Mask))
798 return LT.first * getRISCVInstructionCost(RISCV::VNSRL_WI,
803 if (LT.second.getScalarSizeInBits() != 1 &&
806 unsigned NumSlides =
Log2_32(Mask.size() / SubVectorSize);
808 for (
unsigned I = 0;
I != NumSlides; ++
I) {
809 unsigned InsertIndex = SubVectorSize * (1 <<
I);
814 std::pair<InstructionCost, MVT> DestLT =
819 Cost += DestLT.first * TLI->getLMULCost(DestLT.second);
833 if (LT.first == 1 && (LT.second.getScalarSizeInBits() != 8 ||
834 LT.second.getVectorNumElements() <= 256)) {
839 getRISCVInstructionCost(RISCV::VRGATHER_VV, LT.second,
CostKind);
853 if (LT.first == 1 && (LT.second.getScalarSizeInBits() != 8 ||
854 LT.second.getVectorNumElements() <= 256)) {
855 auto &
C = SrcTy->getContext();
856 auto EC = SrcTy->getElementCount();
861 return 2 * IndexCost +
862 getRISCVInstructionCost({RISCV::VRGATHER_VV, RISCV::VRGATHER_VV},
881 if (!Mask.empty() && LT.first.isValid() && LT.first != 1 &&
909 SubLT.second.isValid() && SubLT.second.isFixedLengthVector()) {
910 if (std::optional<unsigned> VLen = ST->getRealVLen();
911 VLen && SubLT.second.getScalarSizeInBits() * Index % *VLen == 0 &&
912 SubLT.second.getSizeInBits() <= *VLen)
920 getRISCVInstructionCost(RISCV::VSLIDEDOWN_VI, LT.second,
CostKind);
927 getRISCVInstructionCost(RISCV::VSLIDEUP_VI, LT.second,
CostKind);
939 (1 + getRISCVInstructionCost({RISCV::VMV_S_X, RISCV::VMERGE_VVM},
946 if (IsLoad && LT.second.isVector() &&
948 LT.second.getVectorElementCount()))
952 Instruction::InsertElement);
953 if (LT.second.getScalarSizeInBits() == 1) {
961 (1 + getRISCVInstructionCost({RISCV::VMV_V_X, RISCV::VMSNE_VI},
974 (1 + getRISCVInstructionCost({RISCV::VMV_V_I, RISCV::VMERGE_VIM,
975 RISCV::VMV_X_S, RISCV::VMV_V_X,
984 getRISCVInstructionCost(RISCV::VMV_V_X, LT.second,
CostKind);
990 getRISCVInstructionCost(RISCV::VRGATHER_VI, LT.second,
CostKind);
996 unsigned Opcodes[2] = {RISCV::VSLIDEDOWN_VX, RISCV::VSLIDEUP_VX};
997 if (Index >= 0 && Index < 32)
998 Opcodes[0] = RISCV::VSLIDEDOWN_VI;
999 else if (Index < 0 && Index > -32)
1000 Opcodes[1] = RISCV::VSLIDEUP_VI;
1001 return LT.first * getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
1005 if (!LT.second.isVector())
1011 if (SrcTy->getElementType()->isIntegerTy(1)) {
1023 MVT ContainerVT = LT.second;
1024 if (LT.second.isFixedLengthVector())
1025 ContainerVT = TLI->getContainerForFixedLengthVector(LT.second);
1027 if (ContainerVT.
bitsLE(M1VT)) {
1037 if (LT.second.isFixedLengthVector())
1039 LenCost =
isInt<5>(LT.second.getVectorNumElements() - 1) ? 0 : 1;
1040 unsigned Opcodes[] = {RISCV::VID_V, RISCV::VRSUB_VX, RISCV::VRGATHER_VV};
1041 if (LT.second.isFixedLengthVector() &&
1042 isInt<5>(LT.second.getVectorNumElements() - 1))
1043 Opcodes[1] = RISCV::VRSUB_VI;
1045 getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
1046 return LT.first * (LenCost + GatherCost);
1053 unsigned M1Opcodes[] = {RISCV::VID_V, RISCV::VRSUB_VX};
1055 getRISCVInstructionCost(M1Opcodes, M1VT,
CostKind) + 3;
1059 getRISCVInstructionCost({RISCV::VRGATHER_VV}, M1VT,
CostKind) * Ratio;
1061 getRISCVInstructionCost({RISCV::VSLIDEDOWN_VX}, LT.second,
CostKind);
1062 return FixedCost + LT.first * (GatherCost + SlideCost);
1096 Ty, DemandedElts, Insert, Extract,
CostKind);
1098 if (Insert && !Extract && LT.first.isValid() && LT.second.isVector()) {
1099 if (Ty->getScalarSizeInBits() == 1) {
1109 assert(LT.second.isFixedLengthVector());
1110 MVT ContainerVT = TLI->getContainerForFixedLengthVector(LT.second);
1114 getRISCVInstructionCost(RISCV::VSLIDE1DOWN_VX, LT.second,
CostKind);
1127 switch (MICA.
getID()) {
1128 case Intrinsic::vp_load_ff: {
1129 EVT DataTypeVT = TLI->getValueType(
DL, DataTy);
1130 if (!TLI->isLegalFirstFaultLoad(DataTypeVT, Alignment))
1137 case Intrinsic::experimental_vp_strided_load:
1138 case Intrinsic::experimental_vp_strided_store:
1140 case Intrinsic::masked_compressstore:
1141 case Intrinsic::masked_expandload:
1143 case Intrinsic::vp_scatter:
1144 case Intrinsic::vp_gather:
1145 case Intrinsic::masked_scatter:
1146 case Intrinsic::masked_gather:
1148 case Intrinsic::vp_load:
1149 case Intrinsic::vp_store:
1150 case Intrinsic::masked_load:
1151 case Intrinsic::masked_store:
1160 unsigned Opcode = MICA.
getID() == Intrinsic::masked_load ? Instruction::Load
1161 : Instruction::Store;
1176 bool UseMaskForCond,
bool UseMaskForGaps)
const {
1182 if (!UseMaskForGaps && Factor <= TLI->getMaxSupportedInterleaveFactor()) {
1186 if (LT.second.isVector()) {
1192 VTy->getElementCount().divideCoefficientBy(Factor));
1193 if (VTy->getElementCount().isKnownMultipleOf(Factor) &&
1194 TLI->isLegalInterleavedAccessType(SubVecTy, Factor, Alignment,
1199 if (ST->hasOptimizedSegmentLoadStore(Factor)) {
1200 unsigned VecSizeInBits =
1201 getEstimatedVLFor(VTy) * VTy->getScalarSizeInBits();
1202 unsigned VLENForTuning =
1204 unsigned DLENForTuning = VLENForTuning / ST->getDLenFactor();
1206 MVT SubVecVT = getTLI()->getValueType(
DL, SubVecTy).getSimpleVT();
1207 Cost += Factor * TLI->getLMULCost(SubVecVT);
1213 unsigned NumLoads = getEstimatedVLFor(VTy);
1229 if (UseMaskForGaps) {
1232 "Indices should not contain duplicate elements");
1233 unsigned NumOfFields = Indices.
size();
1234 bool IsTailGapOnly = NumOfFields > 1 && (NumOfFields == Indices.
back() + 1);
1235 if (IsTailGapOnly &&
1236 NumOfFields <= TLI->getMaxSupportedInterleaveFactor()) {
1238 if (LT.second.isVector() &&
1239 FVTy->getElementCount().isKnownMultipleOf(Factor)) {
1241 FVTy->getElementType(),
1242 FVTy->getElementCount().divideCoefficientBy(Factor));
1243 if (TLI->isLegalInterleavedAccessType(SubVecTy, NumOfFields, Alignment,
1246 unsigned NumAccesses = getEstimatedVLFor(FVTy);
1255 unsigned VF = FVTy->getNumElements() / Factor;
1262 if (Opcode == Instruction::Load) {
1264 for (
unsigned Index : Indices) {
1268 Mask.resize(VF * Factor, -1);
1272 Cost += ShuffleCost;
1290 UseMaskForCond, UseMaskForGaps);
1292 assert(Opcode == Instruction::Store &&
"Opcode must be a store");
1299 return MemCost + ShuffleCost;
1306 bool IsLoad = MICA.
getID() == Intrinsic::masked_gather ||
1307 MICA.
getID() == Intrinsic::vp_gather;
1308 unsigned Opcode = IsLoad ? Instruction::Load : Instruction::Store;
1314 if ((Opcode == Instruction::Load &&
1316 (Opcode == Instruction::Store &&
1324 unsigned NumLoads = getEstimatedVLFor(&VTy);
1331 unsigned Opcode = MICA.
getID() == Intrinsic::masked_expandload
1333 : Instruction::Store;
1337 bool IsLegal = (Opcode == Instruction::Store &&
1339 (Opcode == Instruction::Load &&
1363 if (Opcode == Instruction::Store)
1364 Opcodes.
append({RISCV::VCOMPRESS_VM});
1366 Opcodes.
append({RISCV::VSETIVLI, RISCV::VIOTA_M, RISCV::VRGATHER_VV});
1368 LT.first * getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
1387 unsigned NumLoads = getEstimatedVLFor(&VTy);
1398 for (
auto *Ty : Tys) {
1399 if (!Ty->isVectorTy())
1413 {Intrinsic::floor, MVT::f32, 9},
1414 {Intrinsic::floor, MVT::f64, 9},
1415 {Intrinsic::ceil, MVT::f32, 9},
1416 {Intrinsic::ceil, MVT::f64, 9},
1417 {Intrinsic::trunc, MVT::f32, 7},
1418 {Intrinsic::trunc, MVT::f64, 7},
1419 {Intrinsic::round, MVT::f32, 9},
1420 {Intrinsic::round, MVT::f64, 9},
1421 {Intrinsic::roundeven, MVT::f32, 9},
1422 {Intrinsic::roundeven, MVT::f64, 9},
1423 {Intrinsic::rint, MVT::f32, 7},
1424 {Intrinsic::rint, MVT::f64, 7},
1425 {Intrinsic::nearbyint, MVT::f32, 9},
1426 {Intrinsic::nearbyint, MVT::f64, 9},
1427 {Intrinsic::bswap, MVT::i16, 3},
1428 {Intrinsic::bswap, MVT::i32, 12},
1429 {Intrinsic::bswap, MVT::i64, 31},
1430 {Intrinsic::bitreverse, MVT::i8, 17},
1431 {Intrinsic::bitreverse, MVT::i16, 24},
1432 {Intrinsic::bitreverse, MVT::i32, 33},
1433 {Intrinsic::bitreverse, MVT::i64, 52},
1434 {Intrinsic::ctpop, MVT::i8, 12},
1435 {Intrinsic::ctpop, MVT::i16, 19},
1436 {Intrinsic::ctpop, MVT::i32, 20},
1437 {Intrinsic::ctpop, MVT::i64, 21},
1438 {Intrinsic::ctlz, MVT::i8, 19},
1439 {Intrinsic::ctlz, MVT::i16, 28},
1440 {Intrinsic::ctlz, MVT::i32, 31},
1441 {Intrinsic::ctlz, MVT::i64, 35},
1442 {Intrinsic::cttz, MVT::i8, 16},
1443 {Intrinsic::cttz, MVT::i16, 23},
1444 {Intrinsic::cttz, MVT::i32, 24},
1445 {Intrinsic::cttz, MVT::i64, 25},
1452 switch (ICA.
getID()) {
1453 case Intrinsic::lrint:
1454 case Intrinsic::llrint:
1455 case Intrinsic::lround:
1456 case Intrinsic::llround: {
1460 if (ST->hasVInstructions() && LT.second.isVector()) {
1462 unsigned SrcEltSz =
DL.getTypeSizeInBits(SrcTy->getScalarType());
1463 unsigned DstEltSz =
DL.getTypeSizeInBits(RetTy->getScalarType());
1464 if (LT.second.getVectorElementType() == MVT::bf16) {
1465 if (!ST->hasVInstructionsBF16Minimal())
1468 Ops = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFCVT_X_F_V};
1470 Ops = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFWCVT_X_F_V};
1471 }
else if (LT.second.getVectorElementType() == MVT::f16 &&
1472 !ST->hasVInstructionsF16()) {
1473 if (!ST->hasVInstructionsF16Minimal())
1476 Ops = {RISCV::VFWCVT_F_F_V, RISCV::VFCVT_X_F_V};
1478 Ops = {RISCV::VFWCVT_F_F_V, RISCV::VFWCVT_X_F_V};
1480 }
else if (SrcEltSz > DstEltSz) {
1481 Ops = {RISCV::VFNCVT_X_F_W};
1482 }
else if (SrcEltSz < DstEltSz) {
1483 Ops = {RISCV::VFWCVT_X_F_V};
1485 Ops = {RISCV::VFCVT_X_F_V};
1490 if (SrcEltSz > DstEltSz)
1491 return SrcLT.first *
1492 getRISCVInstructionCost(
Ops, SrcLT.second,
CostKind);
1493 return LT.first * getRISCVInstructionCost(
Ops, LT.second,
CostKind);
1497 case Intrinsic::ceil:
1498 case Intrinsic::floor:
1499 case Intrinsic::trunc:
1500 case Intrinsic::rint:
1501 case Intrinsic::round:
1502 case Intrinsic::roundeven: {
1505 if (!LT.second.isVector() && TLI->isOperationCustom(
ISD::FCEIL, LT.second))
1506 return LT.first * 8;
1509 case Intrinsic::umin:
1510 case Intrinsic::umax:
1511 case Intrinsic::smin:
1512 case Intrinsic::smax: {
1514 if (LT.second.isScalarInteger() && ST->hasStdExtZbb())
1517 if (ST->hasVInstructions() && LT.second.isVector()) {
1519 switch (ICA.
getID()) {
1520 case Intrinsic::umin:
1521 Op = RISCV::VMINU_VV;
1523 case Intrinsic::umax:
1524 Op = RISCV::VMAXU_VV;
1526 case Intrinsic::smin:
1527 Op = RISCV::VMIN_VV;
1529 case Intrinsic::smax:
1530 Op = RISCV::VMAX_VV;
1533 return LT.first * getRISCVInstructionCost(
Op, LT.second,
CostKind);
1537 case Intrinsic::sadd_sat:
1538 case Intrinsic::ssub_sat:
1539 case Intrinsic::uadd_sat:
1540 case Intrinsic::usub_sat: {
1542 if (ST->hasVInstructions() && LT.second.isVector()) {
1544 switch (ICA.
getID()) {
1545 case Intrinsic::sadd_sat:
1546 Op = RISCV::VSADD_VV;
1548 case Intrinsic::ssub_sat:
1549 Op = RISCV::VSSUB_VV;
1551 case Intrinsic::uadd_sat:
1552 Op = RISCV::VSADDU_VV;
1554 case Intrinsic::usub_sat:
1555 Op = RISCV::VSSUBU_VV;
1558 return LT.first * getRISCVInstructionCost(
Op, LT.second,
CostKind);
1562 case Intrinsic::fma:
1563 case Intrinsic::fmuladd: {
1566 if (ST->hasVInstructions() && LT.second.isVector())
1568 getRISCVInstructionCost(RISCV::VFMADD_VV, LT.second,
CostKind);
1571 case Intrinsic::fabs: {
1573 if (ST->hasVInstructions() && LT.second.isVector()) {
1579 if (LT.second.getVectorElementType() == MVT::bf16 ||
1580 (LT.second.getVectorElementType() == MVT::f16 &&
1581 !ST->hasVInstructionsF16()))
1582 return LT.first * getRISCVInstructionCost(RISCV::VAND_VX, LT.second,
1587 getRISCVInstructionCost(RISCV::VFSGNJX_VV, LT.second,
CostKind);
1591 case Intrinsic::sqrt: {
1593 if (ST->hasVInstructions() && LT.second.isVector()) {
1596 MVT ConvType = LT.second;
1597 MVT FsqrtType = LT.second;
1600 if (LT.second.getVectorElementType() == MVT::bf16) {
1601 if (LT.second == MVT::nxv32bf16) {
1602 ConvOp = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFWCVTBF16_F_F_V,
1603 RISCV::VFNCVTBF16_F_F_W, RISCV::VFNCVTBF16_F_F_W};
1604 FsqrtOp = {RISCV::VFSQRT_V, RISCV::VFSQRT_V};
1605 ConvType = MVT::nxv16f16;
1606 FsqrtType = MVT::nxv16f32;
1608 ConvOp = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFNCVTBF16_F_F_W};
1609 FsqrtOp = {RISCV::VFSQRT_V};
1610 FsqrtType = TLI->getTypeToPromoteTo(
ISD::FSQRT, FsqrtType);
1612 }
else if (LT.second.getVectorElementType() == MVT::f16 &&
1613 !ST->hasVInstructionsF16()) {
1614 if (LT.second == MVT::nxv32f16) {
1615 ConvOp = {RISCV::VFWCVT_F_F_V, RISCV::VFWCVT_F_F_V,
1616 RISCV::VFNCVT_F_F_W, RISCV::VFNCVT_F_F_W};
1617 FsqrtOp = {RISCV::VFSQRT_V, RISCV::VFSQRT_V};
1618 ConvType = MVT::nxv16f16;
1619 FsqrtType = MVT::nxv16f32;
1621 ConvOp = {RISCV::VFWCVT_F_F_V, RISCV::VFNCVT_F_F_W};
1622 FsqrtOp = {RISCV::VFSQRT_V};
1623 FsqrtType = TLI->getTypeToPromoteTo(
ISD::FSQRT, FsqrtType);
1626 FsqrtOp = {RISCV::VFSQRT_V};
1629 return LT.first * (getRISCVInstructionCost(FsqrtOp, FsqrtType,
CostKind) +
1630 getRISCVInstructionCost(ConvOp, ConvType,
CostKind));
1634 case Intrinsic::cttz:
1635 case Intrinsic::ctlz:
1636 case Intrinsic::ctpop: {
1638 if (ST->hasStdExtZvbb() && LT.second.isVector()) {
1640 switch (ICA.
getID()) {
1641 case Intrinsic::cttz:
1644 case Intrinsic::ctlz:
1647 case Intrinsic::ctpop:
1648 Op = RISCV::VCPOP_V;
1651 return LT.first * getRISCVInstructionCost(
Op, LT.second,
CostKind);
1655 case Intrinsic::abs: {
1657 if (ST->hasVInstructions() && LT.second.isVector()) {
1659 if (ST->hasStdExtZvabd())
1661 getRISCVInstructionCost({RISCV::VABD_VX}, LT.second,
CostKind);
1666 getRISCVInstructionCost({RISCV::VRSUB_VI, RISCV::VMAX_VV},
1671 case Intrinsic::fshl:
1672 case Intrinsic::fshr: {
1679 if ((ST->hasStdExtZbb() || ST->hasStdExtZbkb()) && RetTy->isIntegerTy() &&
1681 (RetTy->getIntegerBitWidth() == 32 ||
1682 RetTy->getIntegerBitWidth() == 64) &&
1683 RetTy->getIntegerBitWidth() <= ST->getXLen()) {
1688 case Intrinsic::clmul: {
1690 if (!LT.second.isVector() && ST->hasStdExtZvbc() && !ST->hasStdExtZbc() &&
1691 !ST->hasStdExtZbkc()) {
1694 if (!ST->is64Bit() || LT.second != MVT::i64)
1700 return LT.first * getRISCVInstructionCost(
1701 {RISCV::VMV_S_X, RISCV::VCLMUL_VX, RISCV::VMV_X_S},
1706 case Intrinsic::masked_udiv:
1709 case Intrinsic::masked_sdiv:
1712 case Intrinsic::masked_urem:
1715 case Intrinsic::masked_srem:
1718 case Intrinsic::get_active_lane_mask: {
1719 if (ST->hasVInstructions()) {
1728 getRISCVInstructionCost({RISCV::VSADDU_VX, RISCV::VMSLTU_VX},
1734 case Intrinsic::stepvector: {
1738 if (ST->hasVInstructions())
1739 return getRISCVInstructionCost(RISCV::VID_V, LT.second,
CostKind) +
1741 getRISCVInstructionCost(RISCV::VADD_VX, LT.second,
CostKind);
1742 return 1 + (LT.first - 1);
1744 case Intrinsic::vector_splice_left:
1745 case Intrinsic::vector_splice_right: {
1750 if (ST->hasVInstructions() && LT.second.isVector()) {
1752 getRISCVInstructionCost({RISCV::VSLIDEDOWN_VX, RISCV::VSLIDEUP_VX},
1757 case Intrinsic::experimental_cttz_elts: {
1758 if (!ST->hasVInstructions())
1765 if (LT.second.getVectorElementType() != MVT::i1)
1766 Cost += getRISCVInstructionCost(RISCV::VMSNE_VI, LT.second,
CostKind);
1768 Cost += getRISCVInstructionCost(RISCV::VFIRST_M, LT.second,
CostKind);
1780 return LT.first *
Cost;
1782 case Intrinsic::experimental_vp_splice: {
1790 case Intrinsic::vp_merge: {
1798 case Intrinsic::fptoui_sat:
1799 case Intrinsic::fptosi_sat: {
1801 bool IsSigned = ICA.
getID() == Intrinsic::fptosi_sat;
1806 if (!SrcTy->isVectorTy())
1809 if (!SrcLT.first.isValid() || !DstLT.first.isValid())
1826 case Intrinsic::experimental_vector_extract_last_active: {
1848 unsigned EltWidth = getTLI()->getBitWidthForCttzElements(
1849 TLI->getVectorIdxTy(
getDataLayout()), MaskTy->getElementCount(),
1850 true, &VScaleRange);
1851 EltWidth = std::max(EltWidth, MaskTy->getScalarSizeInBits());
1859 if (StepLT.first > 1)
1863 unsigned Opcodes[] = {RISCV::VID_V, RISCV::VREDMAXU_VS, RISCV::VMV_X_S};
1865 Cost += MaskLT.first *
1866 getRISCVInstructionCost(RISCV::VCPOP_M, MaskLT.second,
CostKind);
1868 Cost += StepLT.first *
1869 getRISCVInstructionCost(Opcodes, StepLT.second,
CostKind);
1873 Cost += ValLT.first *
1874 getRISCVInstructionCost({RISCV::VSLIDEDOWN_VI, RISCV::VMV_X_S},
1880 if (ST->hasVInstructions() && RetTy->isVectorTy()) {
1882 LT.second.isVector()) {
1883 MVT EltTy = LT.second.getVectorElementType();
1885 ICA.
getID(), EltTy))
1886 return LT.first * Entry->Cost;
1899 if (ST->hasVInstructions() && PtrTy->
isVectorTy())
1917 if (ST->hasStdExtP() &&
1925 if (!ST->hasVInstructions() || Src->getScalarSizeInBits() > ST->getELen() ||
1926 Dst->getScalarSizeInBits() > ST->getELen())
1929 int ISD = TLI->InstructionOpcodeToISD(Opcode);
1944 if (Src->getScalarSizeInBits() == 1) {
1949 return getRISCVInstructionCost(RISCV::VMV_V_I, DstLT.second,
CostKind) +
1950 DstLT.first * getRISCVInstructionCost(RISCV::VMERGE_VIM,
1956 if (Dst->getScalarSizeInBits() == 1) {
1962 return SrcLT.first *
1963 getRISCVInstructionCost({RISCV::VAND_VI, RISCV::VMSNE_VI},
1975 if (!SrcLT.second.isVector() || !DstLT.second.isVector() ||
1976 !SrcLT.first.isValid() || !DstLT.first.isValid() ||
1978 SrcLT.second.getSizeInBits()) ||
1980 DstLT.second.getSizeInBits()) ||
1981 SrcLT.first > 1 || DstLT.first > 1)
1985 assert((SrcLT.first == 1) && (DstLT.first == 1) &&
"Illegal type");
1987 int PowDiff = (int)
Log2_32(DstLT.second.getScalarSizeInBits()) -
1988 (int)
Log2_32(SrcLT.second.getScalarSizeInBits());
1992 if ((PowDiff < 1) || (PowDiff > 3))
1994 unsigned SExtOp[] = {RISCV::VSEXT_VF2, RISCV::VSEXT_VF4, RISCV::VSEXT_VF8};
1995 unsigned ZExtOp[] = {RISCV::VZEXT_VF2, RISCV::VZEXT_VF4, RISCV::VZEXT_VF8};
1998 return getRISCVInstructionCost(
Op, DstLT.second,
CostKind);
2004 unsigned SrcEltSize = SrcLT.second.getScalarSizeInBits();
2005 unsigned DstEltSize = DstLT.second.getScalarSizeInBits();
2009 : RISCV::VFNCVT_F_F_W;
2011 for (; SrcEltSize != DstEltSize;) {
2015 MVT DstMVT = DstLT.second.changeVectorElementType(ElementMVT);
2017 (DstEltSize > SrcEltSize) ? DstEltSize >> 1 : DstEltSize << 1;
2025 unsigned FCVT = IsSigned ? RISCV::VFCVT_RTZ_X_F_V : RISCV::VFCVT_RTZ_XU_F_V;
2027 IsSigned ? RISCV::VFWCVT_RTZ_X_F_V : RISCV::VFWCVT_RTZ_XU_F_V;
2029 IsSigned ? RISCV::VFNCVT_RTZ_X_F_W : RISCV::VFNCVT_RTZ_XU_F_W;
2030 unsigned SrcEltSize = Src->getScalarSizeInBits();
2031 unsigned DstEltSize = Dst->getScalarSizeInBits();
2033 if ((SrcEltSize == 16) &&
2034 (!ST->hasVInstructionsF16() || ((DstEltSize / 2) > SrcEltSize))) {
2040 std::pair<InstructionCost, MVT> VecF32LT =
2043 VecF32LT.first * getRISCVInstructionCost(RISCV::VFWCVT_F_F_V,
2048 if (DstEltSize == SrcEltSize)
2049 Cost += getRISCVInstructionCost(FCVT, DstLT.second,
CostKind);
2050 else if (DstEltSize > SrcEltSize)
2051 Cost += getRISCVInstructionCost(FWCVT, DstLT.second,
CostKind);
2056 MVT VecVT = DstLT.second.changeVectorElementType(ElementVT);
2057 Cost += getRISCVInstructionCost(FNCVT, VecVT,
CostKind);
2058 if ((SrcEltSize / 2) > DstEltSize) {
2069 unsigned FCVT = IsSigned ? RISCV::VFCVT_F_X_V : RISCV::VFCVT_F_XU_V;
2070 unsigned FWCVT = IsSigned ? RISCV::VFWCVT_F_X_V : RISCV::VFWCVT_F_XU_V;
2071 unsigned FNCVT = IsSigned ? RISCV::VFNCVT_F_X_W : RISCV::VFNCVT_F_XU_W;
2072 unsigned SrcEltSize = Src->getScalarSizeInBits();
2073 unsigned DstEltSize = Dst->getScalarSizeInBits();
2076 if ((DstEltSize == 16) &&
2077 (!ST->hasVInstructionsF16() || ((SrcEltSize / 2) > DstEltSize))) {
2083 std::pair<InstructionCost, MVT> VecF32LT =
2086 Cost += VecF32LT.first * getRISCVInstructionCost(RISCV::VFNCVT_F_F_W,
2091 if (DstEltSize == SrcEltSize)
2092 Cost += getRISCVInstructionCost(FCVT, DstLT.second,
CostKind);
2093 else if (DstEltSize > SrcEltSize) {
2094 if ((DstEltSize / 2) > SrcEltSize) {
2098 unsigned Op = IsSigned ? Instruction::SExt : Instruction::ZExt;
2101 Cost += getRISCVInstructionCost(FWCVT, DstLT.second,
CostKind);
2103 Cost += getRISCVInstructionCost(FNCVT, DstLT.second,
CostKind);
2110unsigned RISCVTTIImpl::getEstimatedVLFor(
VectorType *Ty)
const {
2112 const unsigned EltSize =
DL.getTypeSizeInBits(Ty->getElementType());
2113 const unsigned MinSize =
DL.getTypeSizeInBits(Ty).getKnownMinValue();
2128 if (Ty->getScalarSizeInBits() > ST->getELen())
2132 if (Ty->getElementType()->isIntegerTy(1)) {
2136 if (IID == Intrinsic::umax || IID == Intrinsic::smin)
2142 if (IID == Intrinsic::maximum || IID == Intrinsic::minimum) {
2146 case Intrinsic::maximum:
2148 Opcodes = {RISCV::VFREDMAX_VS, RISCV::VFMV_F_S};
2150 Opcodes = {RISCV::VMFNE_VV, RISCV::VCPOP_M, RISCV::VFREDMAX_VS,
2165 case Intrinsic::minimum:
2167 Opcodes = {RISCV::VFREDMIN_VS, RISCV::VFMV_F_S};
2169 Opcodes = {RISCV::VMFNE_VV, RISCV::VCPOP_M, RISCV::VFREDMIN_VS,
2175 const unsigned EltTyBits =
DL.getTypeSizeInBits(DstTy);
2184 return ExtraCost + getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2193 case Intrinsic::smax:
2194 SplitOp = RISCV::VMAX_VV;
2195 Opcodes = {RISCV::VREDMAX_VS, RISCV::VMV_X_S};
2197 case Intrinsic::smin:
2198 SplitOp = RISCV::VMIN_VV;
2199 Opcodes = {RISCV::VREDMIN_VS, RISCV::VMV_X_S};
2201 case Intrinsic::umax:
2202 SplitOp = RISCV::VMAXU_VV;
2203 Opcodes = {RISCV::VREDMAXU_VS, RISCV::VMV_X_S};
2205 case Intrinsic::umin:
2206 SplitOp = RISCV::VMINU_VV;
2207 Opcodes = {RISCV::VREDMINU_VS, RISCV::VMV_X_S};
2209 case Intrinsic::maxnum:
2210 SplitOp = RISCV::VFMAX_VV;
2211 Opcodes = {RISCV::VFREDMAX_VS, RISCV::VFMV_F_S};
2213 case Intrinsic::minnum:
2214 SplitOp = RISCV::VFMIN_VV;
2215 Opcodes = {RISCV::VFREDMIN_VS, RISCV::VFMV_F_S};
2220 (LT.first > 1) ? (LT.first - 1) *
2221 getRISCVInstructionCost(SplitOp, LT.second,
CostKind)
2223 return SplitCost + getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2228 std::optional<FastMathFlags> FMF,
2234 if (Ty->getScalarSizeInBits() > ST->getELen())
2237 int ISD = TLI->InstructionOpcodeToISD(Opcode);
2245 Type *ElementTy = Ty->getElementType();
2250 if (LT.second == MVT::v1i1)
2251 return getRISCVInstructionCost(RISCV::VFIRST_M, LT.second,
CostKind) +
2269 return ((LT.first > 2) ? (LT.first - 2) : 0) *
2270 getRISCVInstructionCost(RISCV::VMAND_MM, LT.second,
CostKind) +
2271 getRISCVInstructionCost(RISCV::VMNAND_MM, LT.second,
CostKind) +
2272 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind) +
2281 return (LT.first - 1) *
2282 getRISCVInstructionCost(RISCV::VMXOR_MM, LT.second,
CostKind) +
2283 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind) + 1;
2291 return (LT.first - 1) *
2292 getRISCVInstructionCost(RISCV::VMOR_MM, LT.second,
CostKind) +
2293 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind) +
2306 SplitOp = RISCV::VADD_VV;
2307 Opcodes = {RISCV::VMV_S_X, RISCV::VREDSUM_VS, RISCV::VMV_X_S};
2310 SplitOp = RISCV::VOR_VV;
2311 Opcodes = {RISCV::VREDOR_VS, RISCV::VMV_X_S};
2314 SplitOp = RISCV::VXOR_VV;
2315 Opcodes = {RISCV::VMV_S_X, RISCV::VREDXOR_VS, RISCV::VMV_X_S};
2318 SplitOp = RISCV::VAND_VV;
2319 Opcodes = {RISCV::VREDAND_VS, RISCV::VMV_X_S};
2323 if ((LT.second.getScalarType() == MVT::f16 && !ST->hasVInstructionsF16()) ||
2324 LT.second.getScalarType() == MVT::bf16)
2328 for (
unsigned i = 0; i < LT.first.getValue(); i++)
2331 return getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2333 SplitOp = RISCV::VFADD_VV;
2334 Opcodes = {RISCV::VFMV_S_F, RISCV::VFREDUSUM_VS, RISCV::VFMV_F_S};
2339 (LT.first > 1) ? (LT.first - 1) *
2340 getRISCVInstructionCost(SplitOp, LT.second,
CostKind)
2342 return SplitCost + getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2346 unsigned Opcode,
bool IsUnsigned,
Type *ResTy,
VectorType *ValTy,
2357 if (Opcode != Instruction::Add && Opcode != Instruction::FAdd)
2363 if (IsUnsigned && Opcode == Instruction::Add &&
2364 LT.second.isFixedLengthVectorOf(MVT::i1)) {
2368 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind);
2375 return (LT.first - 1) +
2382 assert(OpInfo.isConstant() &&
"non constant operand?");
2389 if (OpInfo.isUniform())
2395 return getConstantPoolLoadCost(Ty,
CostKind);
2404 EVT VT = TLI->getValueType(
DL, Src,
true);
2406 if (VT == MVT::Other ||
2412 if (Opcode == Instruction::Store && OpInfo.isConstant())
2427 if (Src->
isVectorTy() && LT.second.isVector() &&
2429 LT.second.getSizeInBits()))
2439 if (ST->hasVInstructions() && LT.second.isVector() &&
2441 BaseCost *= TLI->getLMULCost(LT.second);
2442 return Cost + BaseCost;
2451 Op1Info, Op2Info,
I);
2455 Op1Info, Op2Info,
I);
2460 Op1Info, Op2Info,
I);
2462 auto GetConstantMatCost =
2464 if (OpInfo.isUniform())
2469 return getConstantPoolLoadCost(ValTy,
CostKind);
2474 ConstantMatCost += GetConstantMatCost(Op1Info);
2476 ConstantMatCost += GetConstantMatCost(Op2Info);
2479 if (Opcode == Instruction::Select && LT.second.isVector()) {
2480 if (CondTy->isVectorTy()) {
2485 return ConstantMatCost +
2487 getRISCVInstructionCost(
2488 {RISCV::VMANDN_MM, RISCV::VMAND_MM, RISCV::VMOR_MM},
2492 return ConstantMatCost +
2493 LT.first * getRISCVInstructionCost(RISCV::VMERGE_VVM, LT.second,
2503 MVT InterimVT = LT.second.changeVectorElementType(MVT::i8);
2504 return ConstantMatCost +
2506 getRISCVInstructionCost({RISCV::VMV_V_X, RISCV::VMSNE_VI},
2508 LT.first * getRISCVInstructionCost(
2509 {RISCV::VMANDN_MM, RISCV::VMAND_MM, RISCV::VMOR_MM},
2516 return ConstantMatCost +
2517 LT.first * getRISCVInstructionCost(
2518 {RISCV::VMV_V_X, RISCV::VMSNE_VI, RISCV::VMERGE_VVM},
2522 if ((Opcode == Instruction::ICmp) && ValTy->
isVectorTy() &&
2526 return ConstantMatCost + LT.first * getRISCVInstructionCost(RISCV::VMSLT_VV,
2531 if ((Opcode == Instruction::FCmp) && ValTy->
isVectorTy() &&
2536 return ConstantMatCost +
2537 getRISCVInstructionCost(RISCV::VMXOR_MM, LT.second,
CostKind);
2547 Op1Info, Op2Info,
I);
2556 return ConstantMatCost +
2557 LT.first * getRISCVInstructionCost(
2558 {RISCV::VMFLT_VV, RISCV::VMFLT_VV, RISCV::VMOR_MM},
2565 return ConstantMatCost +
2567 getRISCVInstructionCost({RISCV::VMFLT_VV, RISCV::VMNAND_MM},
2576 return ConstantMatCost +
2578 getRISCVInstructionCost(RISCV::VMFLT_VV, LT.second,
CostKind);
2591 return match(U, m_Select(m_Specific(I), m_Value(), m_Value())) &&
2592 U->getType()->isIntegerTy() &&
2593 !isa<ConstantData>(U->getOperand(1)) &&
2594 !isa<ConstantData>(U->getOperand(2));
2602 Op1Info, Op2Info,
I);
2609 return Opcode == Instruction::PHI ? 0 : 1;
2626 if (Opcode != Instruction::ExtractElement &&
2627 Opcode != Instruction::InsertElement)
2635 if (!LT.second.isVector()) {
2644 Type *ElemTy = FixedVecTy->getElementType();
2645 auto NumElems = FixedVecTy->getNumElements();
2646 auto Align =
DL.getPrefTypeAlign(ElemTy);
2651 return Opcode == Instruction::ExtractElement
2652 ? StoreCost * NumElems + LoadCost
2653 : (StoreCost + LoadCost) * NumElems + StoreCost;
2657 if (LT.second.isScalableVector() && !LT.first.isValid())
2665 if (Opcode == Instruction::ExtractElement) {
2671 return ExtendCost + ExtractCost;
2681 return ExtendCost + InsertCost + TruncCost;
2688 if (LT.second.isFloatingPoint())
2689 MoveOpc = Opcode == Instruction::InsertElement ? RISCV::VFMV_S_F
2693 Opcode == Instruction::InsertElement ? RISCV::VMV_S_X : RISCV::VMV_X_S;
2695 getRISCVInstructionCost(MoveOpc, LT.second,
CostKind);
2697 InstructionCost SlideCost = Opcode == Instruction::InsertElement ? 2 : 1;
2702 if (LT.second.isFixedLengthVector()) {
2703 unsigned Width = LT.second.getVectorNumElements();
2704 Index = Index % Width;
2709 if (
auto VLEN = ST->getRealVLen()) {
2710 unsigned EltSize = LT.second.getScalarSizeInBits();
2711 unsigned M1Max = *VLEN / EltSize;
2712 Index = Index % M1Max;
2718 else if (Opcode == Instruction::InsertElement)
2726 ((Index == -1U) || (Index >= LT.second.getVectorMinNumElements() &&
2727 LT.second.isScalableVector()))) {
2729 Align VecAlign =
DL.getPrefTypeAlign(Val);
2730 Align SclAlign =
DL.getPrefTypeAlign(ScalarType);
2735 if (Opcode == Instruction::ExtractElement)
2771 Opcode == Instruction::InsertElement
2772 ? getRISCVInstructionCost({RISCV::VSLIDE1DOWN_VX,
2773 RISCV::VSLIDE1DOWN_VX,
2774 RISCV::VSLIDEUP_VX},
2776 : getRISCVInstructionCost({RISCV::VSLIDEDOWN_VX, RISCV::VMV_X_S,
2777 RISCV::VSRL_VX, RISCV::VMV_X_S},
2780 return BaseCost + SlideCost;
2786 unsigned Index)
const {
2795 assert(Index < EC.getKnownMinValue() &&
"Unexpected reverse index");
2797 EC.getKnownMinValue() - 1 - Index,
nullptr,
2806std::optional<InstructionCost>
2812 if ((Opcode == Instruction::UDiv || Opcode == Instruction::URem) &&
2814 if (Opcode == Instruction::UDiv)
2821 return std::nullopt;
2843 if (std::optional<InstructionCost> CombinedCost =
2845 Op2Info, Args, CxtI))
2846 return *CombinedCost;
2850 unsigned ISDOpcode = TLI->InstructionOpcodeToISD(Opcode);
2853 if (!LT.second.isVector()) {
2863 if (TLI->isOperationLegalOrPromote(ISDOpcode, LT.second))
2864 if (
const auto *Entry =
CostTableLookup(DivTbl, ISDOpcode, LT.second))
2865 return Entry->Cost * LT.first;
2874 if ((LT.second.getVectorElementType() == MVT::f16 ||
2875 LT.second.getVectorElementType() == MVT::bf16) &&
2876 TLI->getOperationAction(ISDOpcode, LT.second) ==
2878 MVT PromotedVT = TLI->getTypeToPromoteTo(ISDOpcode, LT.second);
2882 CastCost += LT.first * Args.size() *
2890 LT.second = PromotedVT;
2893 auto getConstantMatCost =
2903 return getConstantPoolLoadCost(Ty,
CostKind);
2909 ConstantMatCost += getConstantMatCost(0, Op1Info);
2911 ConstantMatCost += getConstantMatCost(1, Op2Info);
2914 switch (ISDOpcode) {
2917 Op = RISCV::VADD_VV;
2922 Op = RISCV::VSLL_VV;
2927 Op = (Ty->getScalarSizeInBits() == 1) ? RISCV::VMAND_MM : RISCV::VAND_VV;
2932 Op = RISCV::VMUL_VV;
2936 Op = RISCV::VDIV_VV;
2940 Op = RISCV::VREM_VV;
2944 Op = RISCV::VFADD_VV;
2947 Op = RISCV::VFMUL_VV;
2950 Op = RISCV::VFDIV_VV;
2953 Op = RISCV::VFSGNJN_VV;
2958 return CastCost + ConstantMatCost +
2967 if (Ty->isFPOrFPVectorTy())
2969 return CastCost + ConstantMatCost + LT.first *
InstrCost;
2992 if (Info.isSameBase() && V !=
Base) {
2993 if (
GEP->hasAllConstantIndices())
2999 unsigned Stride =
DL.getTypeStoreSize(AccessTy);
3000 if (Info.isUnitStride() &&
3006 GEP->getType()->getPointerAddressSpace()))
3009 {TTI::OK_AnyValue, TTI::OP_None},
3010 {TTI::OK_AnyValue, TTI::OP_None}, {});
3027 if (ST->enableDefaultUnroll())
3037 if (L->getHeader()->getParent()->hasOptSize())
3041 L->getExitingBlocks(ExitingBlocks);
3043 <<
"Blocks: " << L->getNumBlocks() <<
"\n"
3044 <<
"Exit blocks: " << ExitingBlocks.
size() <<
"\n");
3048 if (ExitingBlocks.
size() > 2)
3053 if (L->getNumBlocks() > 4)
3061 for (
auto *BB : L->getBlocks()) {
3062 for (
auto &
I : *BB) {
3066 if (IsVectorized && (
I.getType()->isVectorTy() ||
3068 return V->getType()->isVectorTy();
3109 bool HasMask =
false;
3112 bool IsWrite) -> int64_t {
3113 if (
auto *TarExtTy =
3115 return TarExtTy->getIntParameter(0);
3121 case Intrinsic::riscv_vle_mask:
3122 case Intrinsic::riscv_vse_mask:
3123 case Intrinsic::riscv_vlseg2_mask:
3124 case Intrinsic::riscv_vlseg3_mask:
3125 case Intrinsic::riscv_vlseg4_mask:
3126 case Intrinsic::riscv_vlseg5_mask:
3127 case Intrinsic::riscv_vlseg6_mask:
3128 case Intrinsic::riscv_vlseg7_mask:
3129 case Intrinsic::riscv_vlseg8_mask:
3130 case Intrinsic::riscv_vsseg2_mask:
3131 case Intrinsic::riscv_vsseg3_mask:
3132 case Intrinsic::riscv_vsseg4_mask:
3133 case Intrinsic::riscv_vsseg5_mask:
3134 case Intrinsic::riscv_vsseg6_mask:
3135 case Intrinsic::riscv_vsseg7_mask:
3136 case Intrinsic::riscv_vsseg8_mask:
3139 case Intrinsic::riscv_vle:
3140 case Intrinsic::riscv_vse:
3141 case Intrinsic::riscv_vlseg2:
3142 case Intrinsic::riscv_vlseg3:
3143 case Intrinsic::riscv_vlseg4:
3144 case Intrinsic::riscv_vlseg5:
3145 case Intrinsic::riscv_vlseg6:
3146 case Intrinsic::riscv_vlseg7:
3147 case Intrinsic::riscv_vlseg8:
3148 case Intrinsic::riscv_vsseg2:
3149 case Intrinsic::riscv_vsseg3:
3150 case Intrinsic::riscv_vsseg4:
3151 case Intrinsic::riscv_vsseg5:
3152 case Intrinsic::riscv_vsseg6:
3153 case Intrinsic::riscv_vsseg7:
3154 case Intrinsic::riscv_vsseg8: {
3171 Ty = TarExtTy->getTypeParameter(0U);
3176 const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
3177 unsigned VLIndex = RVVIInfo->VLOperand;
3178 unsigned PtrOperandNo = VLIndex - 1 - HasMask;
3186 unsigned SegNum = getSegNum(Inst, PtrOperandNo, IsWrite);
3189 unsigned ElemSize = Ty->getScalarSizeInBits();
3193 Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty,
3194 Alignment, Mask, EVL);
3197 case Intrinsic::riscv_vlse_mask:
3198 case Intrinsic::riscv_vsse_mask:
3199 case Intrinsic::riscv_vlsseg2_mask:
3200 case Intrinsic::riscv_vlsseg3_mask:
3201 case Intrinsic::riscv_vlsseg4_mask:
3202 case Intrinsic::riscv_vlsseg5_mask:
3203 case Intrinsic::riscv_vlsseg6_mask:
3204 case Intrinsic::riscv_vlsseg7_mask:
3205 case Intrinsic::riscv_vlsseg8_mask:
3206 case Intrinsic::riscv_vssseg2_mask:
3207 case Intrinsic::riscv_vssseg3_mask:
3208 case Intrinsic::riscv_vssseg4_mask:
3209 case Intrinsic::riscv_vssseg5_mask:
3210 case Intrinsic::riscv_vssseg6_mask:
3211 case Intrinsic::riscv_vssseg7_mask:
3212 case Intrinsic::riscv_vssseg8_mask:
3215 case Intrinsic::riscv_vlse:
3216 case Intrinsic::riscv_vsse:
3217 case Intrinsic::riscv_vlsseg2:
3218 case Intrinsic::riscv_vlsseg3:
3219 case Intrinsic::riscv_vlsseg4:
3220 case Intrinsic::riscv_vlsseg5:
3221 case Intrinsic::riscv_vlsseg6:
3222 case Intrinsic::riscv_vlsseg7:
3223 case Intrinsic::riscv_vlsseg8:
3224 case Intrinsic::riscv_vssseg2:
3225 case Intrinsic::riscv_vssseg3:
3226 case Intrinsic::riscv_vssseg4:
3227 case Intrinsic::riscv_vssseg5:
3228 case Intrinsic::riscv_vssseg6:
3229 case Intrinsic::riscv_vssseg7:
3230 case Intrinsic::riscv_vssseg8: {
3247 Ty = TarExtTy->getTypeParameter(0U);
3252 const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
3253 unsigned VLIndex = RVVIInfo->VLOperand;
3254 unsigned PtrOperandNo = VLIndex - 2 - HasMask;
3263 unsigned PointerAlign = Alignment.valueOrOne().value();
3266 Alignment =
Align(1);
3273 unsigned SegNum = getSegNum(Inst, PtrOperandNo, IsWrite);
3276 unsigned ElemSize = Ty->getScalarSizeInBits();
3280 Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty,
3281 Alignment, Mask, EVL, Stride);
3284 case Intrinsic::riscv_vloxei_mask:
3285 case Intrinsic::riscv_vluxei_mask:
3286 case Intrinsic::riscv_vsoxei_mask:
3287 case Intrinsic::riscv_vsuxei_mask:
3288 case Intrinsic::riscv_vloxseg2_mask:
3289 case Intrinsic::riscv_vloxseg3_mask:
3290 case Intrinsic::riscv_vloxseg4_mask:
3291 case Intrinsic::riscv_vloxseg5_mask:
3292 case Intrinsic::riscv_vloxseg6_mask:
3293 case Intrinsic::riscv_vloxseg7_mask:
3294 case Intrinsic::riscv_vloxseg8_mask:
3295 case Intrinsic::riscv_vluxseg2_mask:
3296 case Intrinsic::riscv_vluxseg3_mask:
3297 case Intrinsic::riscv_vluxseg4_mask:
3298 case Intrinsic::riscv_vluxseg5_mask:
3299 case Intrinsic::riscv_vluxseg6_mask:
3300 case Intrinsic::riscv_vluxseg7_mask:
3301 case Intrinsic::riscv_vluxseg8_mask:
3302 case Intrinsic::riscv_vsoxseg2_mask:
3303 case Intrinsic::riscv_vsoxseg3_mask:
3304 case Intrinsic::riscv_vsoxseg4_mask:
3305 case Intrinsic::riscv_vsoxseg5_mask:
3306 case Intrinsic::riscv_vsoxseg6_mask:
3307 case Intrinsic::riscv_vsoxseg7_mask:
3308 case Intrinsic::riscv_vsoxseg8_mask:
3309 case Intrinsic::riscv_vsuxseg2_mask:
3310 case Intrinsic::riscv_vsuxseg3_mask:
3311 case Intrinsic::riscv_vsuxseg4_mask:
3312 case Intrinsic::riscv_vsuxseg5_mask:
3313 case Intrinsic::riscv_vsuxseg6_mask:
3314 case Intrinsic::riscv_vsuxseg7_mask:
3315 case Intrinsic::riscv_vsuxseg8_mask:
3318 case Intrinsic::riscv_vloxei:
3319 case Intrinsic::riscv_vluxei:
3320 case Intrinsic::riscv_vsoxei:
3321 case Intrinsic::riscv_vsuxei:
3322 case Intrinsic::riscv_vloxseg2:
3323 case Intrinsic::riscv_vloxseg3:
3324 case Intrinsic::riscv_vloxseg4:
3325 case Intrinsic::riscv_vloxseg5:
3326 case Intrinsic::riscv_vloxseg6:
3327 case Intrinsic::riscv_vloxseg7:
3328 case Intrinsic::riscv_vloxseg8:
3329 case Intrinsic::riscv_vluxseg2:
3330 case Intrinsic::riscv_vluxseg3:
3331 case Intrinsic::riscv_vluxseg4:
3332 case Intrinsic::riscv_vluxseg5:
3333 case Intrinsic::riscv_vluxseg6:
3334 case Intrinsic::riscv_vluxseg7:
3335 case Intrinsic::riscv_vluxseg8:
3336 case Intrinsic::riscv_vsoxseg2:
3337 case Intrinsic::riscv_vsoxseg3:
3338 case Intrinsic::riscv_vsoxseg4:
3339 case Intrinsic::riscv_vsoxseg5:
3340 case Intrinsic::riscv_vsoxseg6:
3341 case Intrinsic::riscv_vsoxseg7:
3342 case Intrinsic::riscv_vsoxseg8:
3343 case Intrinsic::riscv_vsuxseg2:
3344 case Intrinsic::riscv_vsuxseg3:
3345 case Intrinsic::riscv_vsuxseg4:
3346 case Intrinsic::riscv_vsuxseg5:
3347 case Intrinsic::riscv_vsuxseg6:
3348 case Intrinsic::riscv_vsuxseg7:
3349 case Intrinsic::riscv_vsuxseg8: {
3366 Ty = TarExtTy->getTypeParameter(0U);
3371 const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
3372 unsigned VLIndex = RVVIInfo->VLOperand;
3373 unsigned PtrOperandNo = VLIndex - 2 - HasMask;
3386 unsigned SegNum = getSegNum(Inst, PtrOperandNo, IsWrite);
3389 unsigned ElemSize = Ty->getScalarSizeInBits();
3394 Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty,
3395 Align(1), Mask, EVL,
3404 if (Ty->isVectorTy()) {
3407 if ((EltTy->
isHalfTy() && !ST->hasVInstructionsF16()) ||
3413 if (
Size.isScalable() && ST->hasVInstructions())
3416 if (ST->useRVVForFixedLengthVectors())
3436 return std::max<unsigned>(1U, RegWidth.
getFixedValue() / ElemWidth);
3444 return ST->enableUnalignedVectorMem();
3450 if (ST->hasVendorXCVmem() && !ST->is64Bit())
3472 Align Alignment)
const {
3474 if (!VTy || VTy->isScalableTy())
3482 if (VTy->getElementType()->isIntegerTy(8))
3483 if (VTy->getElementCount().getFixedValue() > 256)
3484 return VTy->getPrimitiveSizeInBits() / ST->getRealMinVLen() <
3485 ST->getMaxLMULForFixedLengthVectors();
3490 Align Alignment)
const {
3492 if (!VTy || VTy->isScalableTy())
3503 if (!ST->hasVInstructions() || !ST->hasOptimizedZeroStrideLoad())
3506 return TLI->isLegalElementTypeForRVV(TLI->getValueType(
DL, ElementTy));
3515 const Instruction &
I,
bool &AllowPromotionWithoutCommonHeader)
const {
3516 bool Considerable =
false;
3517 AllowPromotionWithoutCommonHeader =
false;
3520 Type *ConsideredSExtType =
3522 if (
I.getType() != ConsideredSExtType)
3526 for (
const User *U :
I.users()) {
3528 Considerable =
true;
3532 if (GEPInst->getNumOperands() > 2) {
3533 AllowPromotionWithoutCommonHeader =
true;
3538 return Considerable;
3543 case Instruction::Add:
3544 case Instruction::Sub:
3545 case Instruction::Mul:
3546 case Instruction::And:
3547 case Instruction::Or:
3548 case Instruction::Xor:
3549 case Instruction::FAdd:
3550 case Instruction::FSub:
3551 case Instruction::FMul:
3552 case Instruction::FDiv:
3553 case Instruction::ICmp:
3554 case Instruction::FCmp:
3556 case Instruction::Shl:
3557 case Instruction::LShr:
3558 case Instruction::AShr:
3559 case Instruction::UDiv:
3560 case Instruction::SDiv:
3561 case Instruction::URem:
3562 case Instruction::SRem:
3563 case Instruction::Select:
3564 return Operand == 1;
3571 if (!
I->getType()->isVectorTy() || !ST->hasVInstructions())
3581 switch (
II->getIntrinsicID()) {
3582 case Intrinsic::fma:
3583 case Intrinsic::fmuladd:
3584 return Operand == 0 || Operand == 1;
3585 case Intrinsic::vp_udiv:
3586 case Intrinsic::vp_sdiv:
3587 case Intrinsic::vp_urem:
3588 case Intrinsic::vp_srem:
3589 case Intrinsic::ssub_sat:
3590 case Intrinsic::usub_sat:
3591 return Operand == 1;
3593 case Intrinsic::smin:
3594 case Intrinsic::umin:
3595 case Intrinsic::smax:
3596 case Intrinsic::umax:
3597 case Intrinsic::sadd_sat:
3598 case Intrinsic::uadd_sat:
3599 return Operand == 0 || Operand == 1;
3612 if (
I->isBitwiseLogicOp()) {
3613 if (!
I->getType()->isVectorTy()) {
3614 if (ST->hasStdExtZbb() || ST->hasStdExtZbkb()) {
3615 for (
auto &
Op :
I->operands()) {
3623 }
else if (
I->getOpcode() == Instruction::And && ST->hasStdExtZvkb()) {
3624 for (
auto &
Op :
I->operands()) {
3636 Ops.push_back(&Not);
3637 Ops.push_back(&InsertElt);
3645 if (!
I->getType()->isVectorTy() || !ST->hasVInstructions())
3653 if (!ST->sinkSplatOperands())
3656 for (
auto OpIdx :
enumerate(
I->operands())) {
3676 for (
Use &U :
Op->uses()) {
3683 Use *InsertEltUse = &
Op->getOperandUse(0);
3686 Ops.push_back(&InsertElt->getOperandUse(1));
3687 Ops.push_back(InsertEltUse);
3688 Ops.push_back(&OpIdx.value());
3697 if (!ST->hasStdExtZbb() && !ST->hasStdExtZbkb() && !IsZeroCmp)
3700 Options.AllowOverlappingLoads =
true;
3701 Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize);
3703 if (ST->is64Bit()) {
3704 Options.LoadSizes = {8, 4, 2, 1};
3705 Options.AllowedTailExpansions = {3, 5, 6};
3707 Options.LoadSizes = {4, 2, 1};
3708 Options.AllowedTailExpansions = {3};
3711 if (IsZeroCmp && ST->hasVInstructions()) {
3712 unsigned VLenB = ST->getRealMinVLen() / 8;
3715 unsigned MinSize = ST->getXLen() / 8 + 1;
3716 unsigned MaxSize = VLenB * ST->getMaxLMULForFixedLengthVectors();
3730 if (
I->getOpcode() == Instruction::Or &&
3734 if (
I->getOpcode() == Instruction::Add ||
3735 I->getOpcode() == Instruction::Sub)
3753std::optional<Instruction *>
3759 if (
is_contained({Intrinsic::riscv_vsetvli, Intrinsic::riscv_vsetvlimax},
3760 II.getIntrinsicID())) {
3763 if (!ST->hasVInstructions())
3766 bool HasAVL =
II.getIntrinsicID() == Intrinsic::riscv_vsetvli;
3767 unsigned Offset = HasAVL ? 1 : 0;
3768 unsigned BitWidth =
II.getType()->getIntegerBitWidth();
3790 Value *AVL =
II.getArgOperand(0);
3794 const APInt &
C = AVLC->getValue();
3807 II.getRange().value_or(ConstantRange::getFull(
BitWidth));
3809 if (NewRange != OldRange) {
3810 II.addRangeRetAttr(NewRange);
3820 if (
II.user_empty())
3825 const APInt *Scalar;
3830 return U->getType() == TargetVecTy && match(U, m_BitCast(m_Value()));
3834 unsigned TargetEltBW =
DL.getTypeSizeInBits(TargetVecTy->getElementType());
3835 unsigned SourceEltBW =
DL.getTypeSizeInBits(SourceVecTy->getElementType());
3836 if (TargetEltBW % SourceEltBW)
3838 unsigned TargetScale = TargetEltBW / SourceEltBW;
3839 if (VL % TargetScale || TargetScale == 1)
3841 Type *VLTy =
II.getOperand(2)->getType();
3842 ElementCount SourceEC = SourceVecTy->getElementCount();
3843 unsigned NewEltBW = SourceEltBW * TargetScale;
3845 !
DL.fitsInLegalInteger(NewEltBW))
3848 if (!TLI->isLegalElementTypeForRVV(TLI->getValueType(
DL, NewEltTy)))
3852 assert(SourceVecTy->canLosslesslyBitCastTo(RetTy) &&
3853 "Lossless bitcast between types expected");
3859 RetTy, Intrinsic::riscv_vmv_v_x,
3860 {PoisonValue::get(RetTy), ConstantInt::get(NewEltTy, NewScalar),
3861 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
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
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
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
@ 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.
LLVM_ABI APInt getUnsignedMin() const
Return the smallest unsigned value contained in the ConstantRange.
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 ...
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.
static ConstantRange getNonEmpty(APInt Lower, APInt Upper)
Create non-empty constant range with the given bounds.
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.
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
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...
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 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.
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
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)
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 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.
const APInt & umin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be unsigned.
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...
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
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)
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.