19#include "llvm/IR/IntrinsicsRISCV.h"
28#define DEBUG_TYPE "riscvtti"
36 size_t NumInstr = OpCodes.size();
41 return LMULCost * NumInstr;
43 for (
auto Op : OpCodes) {
45 case RISCV::VRGATHER_VI:
48 case RISCV::VRGATHER_VV:
51 case RISCV::VSLIDEUP_VI:
52 case RISCV::VSLIDEDOWN_VI:
55 case RISCV::VSLIDEUP_VX:
56 case RISCV::VSLIDEDOWN_VX:
59 case RISCV::VREDMAX_VS:
60 case RISCV::VREDMIN_VS:
61 case RISCV::VREDMAXU_VS:
62 case RISCV::VREDMINU_VS:
63 case RISCV::VREDSUM_VS:
64 case RISCV::VREDAND_VS:
65 case RISCV::VREDOR_VS:
66 case RISCV::VREDXOR_VS:
67 case RISCV::VFREDMAX_VS:
68 case RISCV::VFREDMIN_VS:
69 case RISCV::VFREDUSUM_VS: {
76 case RISCV::VFREDOSUM_VS: {
93 case RISCV::VMANDN_MM:
94 case RISCV::VMNAND_MM:
115 assert(Ty->isIntegerTy() &&
116 "getIntImmCost can only estimate cost of materialising integers");
139 if (!BO || !BO->hasOneUse())
142 if (BO->getOpcode() != Instruction::Shl)
153 if (ShAmt == Trailing)
170 if (!Cmp || !Cmp->isEquality())
186 if ((CmpC & Mask) != CmpC)
193 return NewCmpC >= -2048 && NewCmpC <= 2048;
200 assert(Ty->isIntegerTy() &&
201 "getIntImmCost can only estimate cost of materialising integers");
209 bool Takes12BitImm =
false;
210 unsigned ImmArgIdx = ~0U;
213 case Instruction::GetElementPtr:
218 case Instruction::Store: {
223 if (Idx == 1 || !Inst)
228 if (!getTLI()->allowsMemoryAccessForAlignment(
229 Ty->getContext(),
DL, getTLI()->getValueType(
DL, Ty),
236 case Instruction::Load:
239 case Instruction::And:
241 if (
Imm == UINT64_C(0xffff) && ST->hasStdExtZbb())
244 if (
Imm == UINT64_C(0xffffffff) && (!ST->is64Bit() || ST->hasStdExtZba()))
247 if (ST->hasStdExtZbs() && (~
Imm).isPowerOf2())
249 if (Inst && Idx == 1 &&
Imm.getBitWidth() <= ST->getXLen() &&
252 if (Inst && Idx == 1 &&
Imm.getBitWidth() == 64 &&
255 Takes12BitImm =
true;
257 case Instruction::Add:
258 Takes12BitImm =
true;
260 case Instruction::Or:
261 case Instruction::Xor:
263 if (ST->hasStdExtZbs() &&
Imm.isPowerOf2())
265 Takes12BitImm =
true;
267 case Instruction::Mul:
269 if (
Imm.isPowerOf2() ||
Imm.isNegatedPowerOf2())
272 if ((
Imm + 1).isPowerOf2() || (
Imm - 1).isPowerOf2())
275 Takes12BitImm =
true;
277 case Instruction::Sub:
278 case Instruction::Shl:
279 case Instruction::LShr:
280 case Instruction::AShr:
281 Takes12BitImm =
true;
292 if (
Imm.getSignificantBits() <= 64 &&
315 return ST->hasVInstructions();
325 unsigned Opcode,
Type *InputTypeA,
Type *InputTypeB,
Type *AccumType,
329 if (Opcode == Instruction::FAdd)
338 if (!ST->hasStdExtZvdot4a8i() || ST->getELen() < 64 ||
339 Opcode != Instruction::Add || !BinOp || *BinOp != Instruction::Mul ||
340 InputTypeA != InputTypeB || !InputTypeA->
isIntegerTy(8) ||
356 getRISCVInstructionCost(RISCV::VDOT4A_VV, DotLT.second,
CostKind);
365 std::pair<InstructionCost, MVT> AccLT =
373 bool WidenFirst =
false;
374 if (VF.
isScalable() && AccLT.second.isScalableVector()) {
375 MVT NarrowMVT = AccLT.second.changeVectorElementType(MVT::i32);
388 WideLT.first * getRISCVInstructionCost(RISCV::VSEXT_VF2,
391 getRISCVInstructionCost(RISCV::VADD_VV, AccLT.second,
CostKind);
395 std::pair<InstructionCost, MVT> RedLT =
397 Cost += RedLT.first * getRISCVInstructionCost(RISCV::VADD_VV,
399 AccLT.first * getRISCVInstructionCost(RISCV::VWADD_WV,
403 Cost += DotLT.first * getRISCVInstructionCost(RISCV::VSLIDEDOWN_VI,
415 switch (
II->getIntrinsicID()) {
419 case Intrinsic::vector_reduce_mul:
420 case Intrinsic::vector_reduce_fmul:
426 if (ST->hasVInstructions())
427 if (
unsigned MinVLen = ST->getRealMinVLen();
436 std::clamp<unsigned>(ST->getCLOpts().v_register_bit_width_lmul, 1, 8));
442 ST->useRVVForFixedLengthVectors() ? LMUL * ST->getRealMinVLen() : 0);
445 (ST->hasVInstructions() &&
468 return (ST->hasAUIPCADDIFusion() && ST->hasLUIADDIFusion()) ? 1 : 2;
474RISCVTTIImpl::getConstantPoolLoadCost(
Type *Ty,
491 unsigned Size = Mask.size();
494 for (
unsigned I = 0;
I !=
Size; ++
I) {
495 if (
static_cast<unsigned>(Mask[
I]) ==
I)
501 for (
unsigned J =
I + 1; J !=
Size; ++J)
503 if (
static_cast<unsigned>(Mask[J]) != J %
I)
531 "Expected fixed vector type and non-empty mask");
534 unsigned NumOfDests =
divideCeil(Mask.size(), LegalNumElts);
538 if (NumOfDests <= 1 ||
540 Tp->getElementType()->getPrimitiveSizeInBits() ||
541 LegalNumElts >= Tp->getElementCount().getFixedValue())
544 unsigned VecTySize =
TTI.getDataLayout().getTypeStoreSize(Tp);
547 unsigned NumOfSrcs =
divideCeil(VecTySize, LegalVTSize);
551 unsigned NormalizedVF = LegalNumElts * std::max(NumOfSrcs, NumOfDests);
552 unsigned NumOfSrcRegs = NormalizedVF / LegalNumElts;
553 unsigned NumOfDestRegs = NormalizedVF / LegalNumElts;
555 assert(NormalizedVF >= Mask.size() &&
556 "Normalized mask expected to be not shorter than original mask.");
561 NormalizedMask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, []() {},
562 [&](
ArrayRef<int> RegMask,
unsigned SrcReg,
unsigned DestReg) {
565 if (!ReusedSingleSrcShuffles.
insert(std::make_pair(RegMask, SrcReg))
568 Cost +=
TTI.getShuffleCost(
571 SingleOpTy,
CostKind, RegMask, 0,
nullptr);
573 [&](
ArrayRef<int> RegMask,
unsigned Idx1,
unsigned Idx2,
bool NewReg) {
574 Cost +=
TTI.getShuffleCost(
577 SingleOpTy,
CostKind, RegMask, 0,
nullptr);
600 if (!VLen || Mask.empty())
604 LegalVT =
TTI.getTypeLegalizationCost(
610 if (NumOfDests <= 1 ||
612 Tp->getElementType()->getPrimitiveSizeInBits() ||
616 unsigned VecTySize =
TTI.getDataLayout().getTypeStoreSize(Tp);
619 unsigned NumOfSrcs =
divideCeil(VecTySize, LegalVTSize);
625 unsigned NormalizedVF =
630 assert(NormalizedVF >= Mask.size() &&
631 "Normalized mask expected to be not shorter than original mask.");
637 NormalizedMask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, []() {},
638 [&](
ArrayRef<int> RegMask,
unsigned SrcReg,
unsigned DestReg) {
641 if (!ReusedSingleSrcShuffles.
insert(std::make_pair(RegMask, SrcReg))
646 SingleOpTy,
CostKind, RegMask, 0,
nullptr);
648 [&](
ArrayRef<int> RegMask,
unsigned Idx1,
unsigned Idx2,
bool NewReg) {
650 SingleOpTy,
CostKind, RegMask, 0,
nullptr);
657 if ((NumOfDestRegs > 2 && NumShuffles <=
static_cast<int>(NumOfDestRegs)) ||
658 (NumOfDestRegs <= 2 && NumShuffles < 4))
673 if (!
LT.second.isFixedLengthVector())
681 auto GetSlideOpcode = [&](
int SlideAmt) {
683 bool IsVI =
isUInt<5>(std::abs(SlideAmt));
685 return IsVI ? RISCV::VSLIDEDOWN_VI : RISCV::VSLIDEDOWN_VX;
686 return IsVI ? RISCV::VSLIDEUP_VI : RISCV::VSLIDEUP_VX;
689 std::array<std::pair<int, int>, 2> SrcInfo;
693 if (SrcInfo[1].second == 0)
696 if (ST->hasStdExtZvzip() &&
LT.second.getScalarSizeInBits() != 1) {
698 if (
isPairEven(SrcInfo, Mask, Factor) && Factor == 1)
699 return getRISCVInstructionCost(RISCV::VPAIRE_VV,
LT.second,
CostKind);
700 if (
isPairOdd(SrcInfo, Mask, Factor) && Factor == 1)
701 return getRISCVInstructionCost(RISCV::VPAIRO_VV,
LT.second,
CostKind);
705 if (SrcInfo[0].second != 0) {
706 unsigned Opcode = GetSlideOpcode(SrcInfo[0].second);
707 FirstSlideCost = getRISCVInstructionCost(Opcode,
LT.second,
CostKind);
710 if (SrcInfo[1].first == -1)
711 return FirstSlideCost;
714 if (SrcInfo[1].second != 0) {
715 unsigned Opcode = GetSlideOpcode(SrcInfo[1].second);
716 SecondSlideCost = getRISCVInstructionCost(Opcode,
LT.second,
CostKind);
719 getRISCVInstructionCost(RISCV::VMERGE_VVM,
LT.second,
CostKind);
726 return FirstSlideCost + SecondSlideCost + MaskCost;
729std::optional<MVT> RISCVTTIImpl::getZvzipVZIPCostVT(
MVT InterleavedVT)
const {
739 LMULOctuple * std::min(ST->getELen(), ST->getRealMinVLen()))
741 return InterleavedVT;
744std::optional<MVT> RISCVTTIImpl::getZvzipVUNZIPCostVT(
MVT InterleavedVT)
const {
752 return InterleavedVT;
762 "Expected the Mask to match the return size if given");
764 "Expected the same scalar types");
767 if (VIC == TTI::VectorInstrContext::SplatOpFolded &&
783 FVTp && ST->hasVInstructions() && LT.second.isFixedLengthVector()) {
785 *
this, LT.second, ST->getRealVLen(),
787 if (VRegSplittingCost.
isValid())
788 return VRegSplittingCost;
793 if (Mask.size() >= 2) {
794 MVT EltTp = LT.second.getVectorElementType();
805 return 2 * LT.first * TLI->getLMULCost(LT.second);
807 if (Mask[0] == 0 || Mask[0] == 1) {
811 if (
equal(DeinterleaveMask, Mask))
812 return LT.first * getRISCVInstructionCost(RISCV::VNSRL_WI,
817 if (LT.second.getScalarSizeInBits() != 1 &&
820 unsigned NumSlides =
Log2_32(Mask.size() / SubVectorSize);
822 for (
unsigned I = 0;
I != NumSlides; ++
I) {
823 unsigned InsertIndex = SubVectorSize * (1 <<
I);
828 std::pair<InstructionCost, MVT> DestLT =
833 Cost += DestLT.first * TLI->getLMULCost(DestLT.second);
847 if (LT.first == 1 && (LT.second.getScalarSizeInBits() != 8 ||
848 LT.second.getVectorNumElements() <= 256)) {
853 getRISCVInstructionCost(RISCV::VRGATHER_VV, LT.second,
CostKind);
867 if (LT.first == 1 && (LT.second.getScalarSizeInBits() != 8 ||
868 LT.second.getVectorNumElements() <= 256)) {
869 auto &
C = SrcTy->getContext();
870 auto EC = SrcTy->getElementCount();
875 return 2 * IndexCost +
876 getRISCVInstructionCost({RISCV::VRGATHER_VV, RISCV::VRGATHER_VV},
895 if (!Mask.empty() && LT.first.isValid() && LT.first != 1 &&
923 SubLT.second.isValid() && SubLT.second.isFixedLengthVector()) {
924 if (std::optional<unsigned> VLen = ST->getRealVLen();
925 VLen && SubLT.second.getScalarSizeInBits() * Index % *VLen == 0 &&
926 SubLT.second.getSizeInBits() <= *VLen)
934 getRISCVInstructionCost(RISCV::VSLIDEDOWN_VI, LT.second,
CostKind);
941 getRISCVInstructionCost(RISCV::VSLIDEUP_VI, LT.second,
CostKind);
953 (1 + getRISCVInstructionCost({RISCV::VMV_S_X, RISCV::VMERGE_VVM},
960 if (IsLoad && LT.second.isVector() &&
962 LT.second.getVectorElementCount()))
966 Instruction::InsertElement);
967 if (LT.second.getScalarSizeInBits() == 1) {
975 (1 + getRISCVInstructionCost({RISCV::VMV_V_X, RISCV::VMSNE_VI},
988 (1 + getRISCVInstructionCost({RISCV::VMV_V_I, RISCV::VMERGE_VIM,
989 RISCV::VMV_X_S, RISCV::VMV_V_X,
998 getRISCVInstructionCost(RISCV::VMV_V_X, LT.second,
CostKind);
1004 getRISCVInstructionCost(RISCV::VRGATHER_VI, LT.second,
CostKind);
1010 unsigned Opcodes[2] = {RISCV::VSLIDEDOWN_VX, RISCV::VSLIDEUP_VX};
1011 if (Index >= 0 && Index < 32)
1012 Opcodes[0] = RISCV::VSLIDEDOWN_VI;
1013 else if (Index < 0 && Index > -32)
1014 Opcodes[1] = RISCV::VSLIDEUP_VI;
1015 return LT.first * getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
1019 if (!LT.second.isVector())
1025 if (SrcTy->getElementType()->isIntegerTy(1)) {
1037 MVT ContainerVT = LT.second;
1038 if (LT.second.isFixedLengthVector())
1039 ContainerVT = TLI->getContainerForFixedLengthVector(LT.second);
1041 if (ContainerVT.
bitsLE(M1VT)) {
1051 if (LT.second.isFixedLengthVector())
1053 LenCost =
isInt<5>(LT.second.getVectorNumElements() - 1) ? 0 : 1;
1054 unsigned Opcodes[] = {RISCV::VID_V, RISCV::VRSUB_VX, RISCV::VRGATHER_VV};
1055 if (LT.second.isFixedLengthVector() &&
1056 isInt<5>(LT.second.getVectorNumElements() - 1))
1057 Opcodes[1] = RISCV::VRSUB_VI;
1059 getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
1060 return LT.first * (LenCost + GatherCost);
1067 unsigned M1Opcodes[] = {RISCV::VID_V, RISCV::VRSUB_VX};
1069 getRISCVInstructionCost(M1Opcodes, M1VT,
CostKind) + 3;
1073 getRISCVInstructionCost({RISCV::VRGATHER_VV}, M1VT,
CostKind) * Ratio;
1075 getRISCVInstructionCost({RISCV::VSLIDEDOWN_VX}, LT.second,
CostKind);
1076 return FixedCost + LT.first * (GatherCost + SlideCost);
1110 Ty, DemandedElts, Insert, Extract,
CostKind);
1112 if (Insert && !Extract && LT.first.isValid() && LT.second.isVector()) {
1113 if (Ty->getScalarSizeInBits() == 1) {
1123 assert(LT.second.isFixedLengthVector());
1124 MVT ContainerVT = TLI->getContainerForFixedLengthVector(LT.second);
1128 getRISCVInstructionCost(RISCV::VSLIDE1DOWN_VX, LT.second,
CostKind);
1141 switch (MICA.
getID()) {
1142 case Intrinsic::vp_load_ff: {
1143 EVT DataTypeVT = TLI->getValueType(
DL, DataTy);
1144 if (!TLI->isLegalFirstFaultLoad(DataTypeVT, Alignment))
1151 case Intrinsic::experimental_vp_strided_load:
1152 case Intrinsic::experimental_vp_strided_store:
1154 case Intrinsic::masked_compressstore:
1155 case Intrinsic::masked_expandload:
1157 case Intrinsic::vp_scatter:
1158 case Intrinsic::vp_gather:
1159 case Intrinsic::masked_scatter:
1160 case Intrinsic::masked_gather:
1162 case Intrinsic::vp_load:
1163 case Intrinsic::vp_store:
1164 case Intrinsic::masked_load:
1165 case Intrinsic::masked_store:
1174 unsigned Opcode = MICA.
getID() == Intrinsic::masked_load ? Instruction::Load
1175 : Instruction::Store;
1186 if (MICA.
getID() == Intrinsic::vp_load ||
1187 MICA.
getID() == Intrinsic::vp_store) {
1199 bool UseMaskForCond,
bool UseMaskForGaps)
const {
1205 if (!UseMaskForGaps && Factor <= TLI->getMaxSupportedInterleaveFactor()) {
1209 if (LT.second.isVector()) {
1215 VTy->getElementCount().divideCoefficientBy(Factor));
1216 if (VTy->getElementCount().isKnownMultipleOf(Factor) &&
1217 TLI->isLegalInterleavedAccessType(SubVecTy, Factor, Alignment,
1222 if (ST->hasOptimizedSegmentLoadStore(Factor)) {
1223 unsigned VecSizeInBits =
1224 getEstimatedVLFor(VTy) * VTy->getScalarSizeInBits();
1225 unsigned VLENForTuning =
1227 unsigned DLENForTuning = VLENForTuning / ST->getDLenFactor();
1229 MVT SubVecVT = getTLI()->getValueType(
DL, SubVecTy).getSimpleVT();
1230 Cost += Factor * TLI->getLMULCost(SubVecVT);
1236 unsigned NumLoads = getEstimatedVLFor(VTy);
1252 if (UseMaskForGaps) {
1255 "Indices should not contain duplicate elements");
1256 unsigned NumOfFields = Indices.
size();
1257 bool IsTailGapOnly = NumOfFields > 1 && (NumOfFields == Indices.
back() + 1);
1258 if (IsTailGapOnly &&
1259 NumOfFields <= TLI->getMaxSupportedInterleaveFactor()) {
1261 if (LT.second.isVector() &&
1262 FVTy->getElementCount().isKnownMultipleOf(Factor)) {
1264 FVTy->getElementType(),
1265 FVTy->getElementCount().divideCoefficientBy(Factor));
1266 if (TLI->isLegalInterleavedAccessType(SubVecTy, NumOfFields, Alignment,
1269 unsigned NumAccesses = getEstimatedVLFor(FVTy);
1278 unsigned VF = FVTy->getNumElements() / Factor;
1285 if (Opcode == Instruction::Load) {
1287 for (
unsigned Index : Indices) {
1291 Mask.resize(VF * Factor, -1);
1295 Cost += ShuffleCost;
1313 UseMaskForCond, UseMaskForGaps);
1315 assert(Opcode == Instruction::Store &&
"Opcode must be a store");
1322 return MemCost + ShuffleCost;
1329 bool IsLoad = MICA.
getID() == Intrinsic::masked_gather ||
1330 MICA.
getID() == Intrinsic::vp_gather;
1331 unsigned Opcode = IsLoad ? Instruction::Load : Instruction::Store;
1339 if ((Opcode == Instruction::Load &&
1341 (Opcode == Instruction::Store &&
1347 if (MICA.
getID() == Intrinsic::vp_gather ||
1348 MICA.
getID() == Intrinsic::vp_scatter) {
1351 if (DataLT.first > 1)
1353 if (PtrLT.first > 1)
1361 unsigned NumLoads = getEstimatedVLFor(&VTy);
1368 unsigned Opcode = MICA.
getID() == Intrinsic::masked_expandload
1370 : Instruction::Store;
1374 bool IsLegal = (Opcode == Instruction::Store &&
1376 (Opcode == Instruction::Load &&
1400 if (Opcode == Instruction::Store)
1401 Opcodes.
append({RISCV::VCOMPRESS_VM});
1403 Opcodes.
append({RISCV::VSETIVLI, RISCV::VIOTA_M, RISCV::VRGATHER_VV});
1405 LT.first * getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
1430 unsigned NumLoads = getEstimatedVLFor(&VTy);
1433 uint64_t CacheLineBytes = ST->getCacheLineSize();
1434 if (!CacheLineBytes)
1435 CacheLineBytes = 64;
1438 int64_t Stride = StrideCI->getSExtValue();
1440 if (Stride != std::numeric_limits<int64_t>::min() && Stride != 0) {
1441 uint64_t AbsStride = (uint64_t)std::abs(Stride);
1442 if (AbsStride < CacheLineBytes) {
1443 uint64_t MaxCombines = ST->getMaxVectorCoalesceElts();
1444 if ((CacheLineBytes / AbsStride) >= MaxCombines)
1445 NumLoads =
divideCeil(NumLoads, MaxCombines);
1449 NumLoads =
divideCeil((NumLoads * AbsStride), CacheLineBytes);
1463 for (
auto *Ty : Tys) {
1464 if (!Ty->isVectorTy())
1478 {Intrinsic::floor, MVT::f32, 9},
1479 {Intrinsic::floor, MVT::f64, 9},
1480 {Intrinsic::ceil, MVT::f32, 9},
1481 {Intrinsic::ceil, MVT::f64, 9},
1482 {Intrinsic::trunc, MVT::f32, 7},
1483 {Intrinsic::trunc, MVT::f64, 7},
1484 {Intrinsic::round, MVT::f32, 9},
1485 {Intrinsic::round, MVT::f64, 9},
1486 {Intrinsic::roundeven, MVT::f32, 9},
1487 {Intrinsic::roundeven, MVT::f64, 9},
1488 {Intrinsic::rint, MVT::f32, 7},
1489 {Intrinsic::rint, MVT::f64, 7},
1490 {Intrinsic::nearbyint, MVT::f32, 9},
1491 {Intrinsic::nearbyint, MVT::f64, 9},
1492 {Intrinsic::bswap, MVT::i16, 3},
1493 {Intrinsic::bswap, MVT::i32, 12},
1494 {Intrinsic::bswap, MVT::i64, 31},
1495 {Intrinsic::bitreverse, MVT::i8, 17},
1496 {Intrinsic::bitreverse, MVT::i16, 24},
1497 {Intrinsic::bitreverse, MVT::i32, 33},
1498 {Intrinsic::bitreverse, MVT::i64, 52},
1499 {Intrinsic::ctpop, MVT::i8, 12},
1500 {Intrinsic::ctpop, MVT::i16, 19},
1501 {Intrinsic::ctpop, MVT::i32, 20},
1502 {Intrinsic::ctpop, MVT::i64, 21},
1503 {Intrinsic::ctlz, MVT::i8, 19},
1504 {Intrinsic::ctlz, MVT::i16, 28},
1505 {Intrinsic::ctlz, MVT::i32, 31},
1506 {Intrinsic::ctlz, MVT::i64, 35},
1507 {Intrinsic::cttz, MVT::i8, 16},
1508 {Intrinsic::cttz, MVT::i16, 23},
1509 {Intrinsic::cttz, MVT::i32, 24},
1510 {Intrinsic::cttz, MVT::i64, 25},
1517 switch (ICA.
getID()) {
1518 case Intrinsic::lrint:
1519 case Intrinsic::llrint:
1520 case Intrinsic::lround:
1521 case Intrinsic::llround: {
1525 if (ST->hasVInstructions() && LT.second.isVector()) {
1527 unsigned SrcEltSz =
DL.getTypeSizeInBits(SrcTy->getScalarType());
1528 unsigned DstEltSz =
DL.getTypeSizeInBits(RetTy->getScalarType());
1529 if (LT.second.getVectorElementType() == MVT::bf16) {
1530 if (!ST->hasVInstructionsBF16Minimal())
1533 Ops = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFCVT_X_F_V};
1535 Ops = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFWCVT_X_F_V};
1536 }
else if (LT.second.getVectorElementType() == MVT::f16 &&
1537 !ST->hasVInstructionsF16()) {
1538 if (!ST->hasVInstructionsF16Minimal())
1541 Ops = {RISCV::VFWCVT_F_F_V, RISCV::VFCVT_X_F_V};
1543 Ops = {RISCV::VFWCVT_F_F_V, RISCV::VFWCVT_X_F_V};
1545 }
else if (SrcEltSz > DstEltSz) {
1546 Ops = {RISCV::VFNCVT_X_F_W};
1547 }
else if (SrcEltSz < DstEltSz) {
1548 Ops = {RISCV::VFWCVT_X_F_V};
1550 Ops = {RISCV::VFCVT_X_F_V};
1555 if (SrcEltSz > DstEltSz)
1556 return SrcLT.first *
1557 getRISCVInstructionCost(
Ops, SrcLT.second,
CostKind);
1558 return LT.first * getRISCVInstructionCost(
Ops, LT.second,
CostKind);
1562 case Intrinsic::ceil:
1563 case Intrinsic::floor:
1564 case Intrinsic::trunc:
1565 case Intrinsic::rint:
1566 case Intrinsic::round:
1567 case Intrinsic::roundeven: {
1570 if (!LT.second.isVector() && TLI->isOperationCustom(
ISD::FCEIL, LT.second))
1571 return LT.first * 8;
1574 case Intrinsic::umin:
1575 case Intrinsic::umax:
1576 case Intrinsic::smin:
1577 case Intrinsic::smax: {
1579 if (LT.second.isScalarInteger() && ST->hasStdExtZbb())
1582 if (ST->hasVInstructions() && LT.second.isVector()) {
1584 switch (ICA.
getID()) {
1585 case Intrinsic::umin:
1586 Op = RISCV::VMINU_VV;
1588 case Intrinsic::umax:
1589 Op = RISCV::VMAXU_VV;
1591 case Intrinsic::smin:
1592 Op = RISCV::VMIN_VV;
1594 case Intrinsic::smax:
1595 Op = RISCV::VMAX_VV;
1598 return LT.first * getRISCVInstructionCost(
Op, LT.second,
CostKind);
1602 case Intrinsic::sadd_sat:
1603 case Intrinsic::ssub_sat:
1604 case Intrinsic::uadd_sat:
1605 case Intrinsic::usub_sat: {
1607 if (ST->hasVInstructions() && LT.second.isVector()) {
1609 switch (ICA.
getID()) {
1610 case Intrinsic::sadd_sat:
1611 Op = RISCV::VSADD_VV;
1613 case Intrinsic::ssub_sat:
1614 Op = RISCV::VSSUB_VV;
1616 case Intrinsic::uadd_sat:
1617 Op = RISCV::VSADDU_VV;
1619 case Intrinsic::usub_sat:
1620 Op = RISCV::VSSUBU_VV;
1623 return LT.first * getRISCVInstructionCost(
Op, LT.second,
CostKind);
1627 case Intrinsic::fma:
1628 case Intrinsic::fmuladd: {
1631 if (ST->hasVInstructions() && LT.second.isVector())
1633 getRISCVInstructionCost(RISCV::VFMADD_VV, LT.second,
CostKind);
1636 case Intrinsic::fabs: {
1638 if (ST->hasVInstructions() && LT.second.isVector()) {
1644 if (LT.second.getVectorElementType() == MVT::bf16 ||
1645 (LT.second.getVectorElementType() == MVT::f16 &&
1646 !ST->hasVInstructionsF16()))
1647 return LT.first * getRISCVInstructionCost(RISCV::VAND_VX, LT.second,
1652 getRISCVInstructionCost(RISCV::VFSGNJX_VV, LT.second,
CostKind);
1656 case Intrinsic::sqrt: {
1658 if (ST->hasVInstructions() && LT.second.isVector()) {
1661 MVT ConvType = LT.second;
1662 MVT FsqrtType = LT.second;
1665 if (LT.second.getVectorElementType() == MVT::bf16) {
1666 if (LT.second == MVT::nxv32bf16) {
1667 ConvOp = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFWCVTBF16_F_F_V,
1668 RISCV::VFNCVTBF16_F_F_W, RISCV::VFNCVTBF16_F_F_W};
1669 FsqrtOp = {RISCV::VFSQRT_V, RISCV::VFSQRT_V};
1670 ConvType = MVT::nxv16f16;
1671 FsqrtType = MVT::nxv16f32;
1673 ConvOp = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFNCVTBF16_F_F_W};
1674 FsqrtOp = {RISCV::VFSQRT_V};
1675 FsqrtType = TLI->getTypeToPromoteTo(
ISD::FSQRT, FsqrtType);
1677 }
else if (LT.second.getVectorElementType() == MVT::f16 &&
1678 !ST->hasVInstructionsF16()) {
1679 if (LT.second == MVT::nxv32f16) {
1680 ConvOp = {RISCV::VFWCVT_F_F_V, RISCV::VFWCVT_F_F_V,
1681 RISCV::VFNCVT_F_F_W, RISCV::VFNCVT_F_F_W};
1682 FsqrtOp = {RISCV::VFSQRT_V, RISCV::VFSQRT_V};
1683 ConvType = MVT::nxv16f16;
1684 FsqrtType = MVT::nxv16f32;
1686 ConvOp = {RISCV::VFWCVT_F_F_V, RISCV::VFNCVT_F_F_W};
1687 FsqrtOp = {RISCV::VFSQRT_V};
1688 FsqrtType = TLI->getTypeToPromoteTo(
ISD::FSQRT, FsqrtType);
1691 FsqrtOp = {RISCV::VFSQRT_V};
1694 return LT.first * (getRISCVInstructionCost(FsqrtOp, FsqrtType,
CostKind) +
1695 getRISCVInstructionCost(ConvOp, ConvType,
CostKind));
1699 case Intrinsic::cttz:
1700 case Intrinsic::ctlz:
1701 case Intrinsic::ctpop: {
1703 if (ST->hasStdExtZvbb() && LT.second.isVector()) {
1705 switch (ICA.
getID()) {
1706 case Intrinsic::cttz:
1709 case Intrinsic::ctlz:
1712 case Intrinsic::ctpop:
1713 Op = RISCV::VCPOP_V;
1716 return LT.first * getRISCVInstructionCost(
Op, LT.second,
CostKind);
1720 case Intrinsic::abs: {
1722 if (ST->hasVInstructions() && LT.second.isVector()) {
1724 if (ST->hasStdExtZvabd())
1726 getRISCVInstructionCost({RISCV::VABD_VX}, LT.second,
CostKind);
1731 getRISCVInstructionCost({RISCV::VRSUB_VI, RISCV::VMAX_VV},
1736 case Intrinsic::fshl:
1737 case Intrinsic::fshr: {
1744 if ((ST->hasStdExtZbb() || ST->hasStdExtZbkb()) && RetTy->isIntegerTy() &&
1746 (RetTy->getIntegerBitWidth() == 32 ||
1747 RetTy->getIntegerBitWidth() == 64) &&
1748 RetTy->getIntegerBitWidth() <= ST->getXLen()) {
1753 case Intrinsic::clmul: {
1755 if (!LT.second.isVector() && ST->hasStdExtZvbc() && !ST->hasStdExtZbkc()) {
1758 if (!ST->is64Bit() || LT.second != MVT::i64)
1764 return LT.first * getRISCVInstructionCost(
1765 {RISCV::VMV_S_X, RISCV::VCLMUL_VX, RISCV::VMV_X_S},
1770 case Intrinsic::masked_udiv:
1773 case Intrinsic::masked_sdiv:
1776 case Intrinsic::masked_urem:
1779 case Intrinsic::masked_srem:
1782 case Intrinsic::get_active_lane_mask: {
1783 if (ST->hasVInstructions()) {
1792 getRISCVInstructionCost({RISCV::VSADDU_VX, RISCV::VMSLTU_VX},
1798 case Intrinsic::stepvector: {
1802 if (ST->hasVInstructions())
1803 return getRISCVInstructionCost(RISCV::VID_V, LT.second,
CostKind) +
1805 getRISCVInstructionCost(RISCV::VADD_VX, LT.second,
CostKind);
1806 return 1 + (LT.first - 1);
1808 case Intrinsic::vector_splice_left:
1809 case Intrinsic::vector_splice_right: {
1814 if (ST->hasVInstructions() && LT.second.isVector()) {
1816 getRISCVInstructionCost({RISCV::VSLIDEDOWN_VX, RISCV::VSLIDEUP_VX},
1821 case Intrinsic::experimental_cttz_elts: {
1822 if (!ST->hasVInstructions())
1827 if (!LT.second.isVector())
1831 if (LT.second.getVectorElementType() != MVT::i1)
1832 Cost += getRISCVInstructionCost(RISCV::VMSNE_VI, LT.second,
CostKind);
1834 Cost += getRISCVInstructionCost(RISCV::VFIRST_M, LT.second,
CostKind);
1846 return LT.first *
Cost;
1848 case Intrinsic::experimental_vp_splice: {
1856 case Intrinsic::vp_merge: {
1864 case Intrinsic::fptoui_sat:
1865 case Intrinsic::fptosi_sat: {
1867 bool IsSigned = ICA.
getID() == Intrinsic::fptosi_sat;
1872 if (!SrcTy->isVectorTy())
1875 if (!SrcLT.first.isValid() || !DstLT.first.isValid())
1892 case Intrinsic::experimental_vector_extract_last_active: {
1914 unsigned EltWidth = getTLI()->getBitWidthForCttzElements(
1915 TLI->getVectorIdxTy(
getDataLayout()), MaskTy->getElementCount(),
1916 true, &VScaleRange);
1917 EltWidth = std::max(EltWidth, MaskTy->getScalarSizeInBits());
1925 if (StepLT.first > 1)
1929 unsigned Opcodes[] = {RISCV::VID_V, RISCV::VREDMAXU_VS, RISCV::VMV_X_S};
1931 Cost += MaskLT.first *
1932 getRISCVInstructionCost(RISCV::VCPOP_M, MaskLT.second,
CostKind);
1934 Cost += StepLT.first *
1935 getRISCVInstructionCost(Opcodes, StepLT.second,
CostKind);
1939 Cost += ValLT.first *
1940 getRISCVInstructionCost({RISCV::VSLIDEDOWN_VI, RISCV::VMV_X_S},
1944 case Intrinsic::vector_interleave2:
1945 case Intrinsic::vector_deinterleave2: {
1946 if (!ST->hasStdExtZvzip())
1949 bool IsInterleave = ICA.
getID() == Intrinsic::vector_interleave2;
1950 Type *InterleavedTy = IsInterleave ? RetTy : ICA.
getArgTypes().front();
1954 [](
const Value *Arg) { return isa<UndefValue>(Arg); }))
1961 unsigned HalfVF = HalfFVT->getNumElements();
1966 for (
unsigned Start = 0; Start != 2; ++Start)
1973 if (!LT.second.isScalableVector())
1976 if (std::optional<MVT> CostVT = getZvzipVZIPCostVT(LT.second))
1978 getRISCVInstructionCost(RISCV::VZIP_VV, *CostVT,
CostKind);
1979 }
else if (std::optional<MVT> CostVT = getZvzipVUNZIPCostVT(LT.second)) {
1981 getRISCVInstructionCost({RISCV::VUNZIPE_V, RISCV::VUNZIPO_V},
1988 if (ST->hasVInstructions() && RetTy->isVectorTy()) {
1990 LT.second.isVector()) {
1991 MVT EltTy = LT.second.getVectorElementType();
1993 ICA.
getID(), EltTy))
1994 return LT.first * Entry->Cost;
2007 if (ST->hasVInstructions() && PtrTy->
isVectorTy())
2025 if (ST->hasStdExtP() &&
2033 if (!ST->hasVInstructions() || Src->getScalarSizeInBits() > ST->getELen() ||
2034 Dst->getScalarSizeInBits() > ST->getELen())
2037 int ISD = TLI->InstructionOpcodeToISD(Opcode);
2052 if (Src->getScalarSizeInBits() == 1) {
2057 return getRISCVInstructionCost(RISCV::VMV_V_I, DstLT.second,
CostKind) +
2058 DstLT.first * getRISCVInstructionCost(RISCV::VMERGE_VIM,
2064 if (Dst->getScalarSizeInBits() == 1) {
2070 return SrcLT.first *
2071 getRISCVInstructionCost({RISCV::VAND_VI, RISCV::VMSNE_VI},
2083 if (!SrcLT.second.isVector() || !DstLT.second.isVector() ||
2084 !SrcLT.first.isValid() || !DstLT.first.isValid() ||
2086 SrcLT.second.getSizeInBits()) ||
2088 DstLT.second.getSizeInBits()) ||
2089 SrcLT.first > 1 || DstLT.first > 1)
2093 assert((SrcLT.first == 1) && (DstLT.first == 1) &&
"Illegal type");
2095 int PowDiff = (int)
Log2_32(DstLT.second.getScalarSizeInBits()) -
2096 (int)
Log2_32(SrcLT.second.getScalarSizeInBits());
2100 if ((PowDiff < 1) || (PowDiff > 3))
2102 unsigned SExtOp[] = {RISCV::VSEXT_VF2, RISCV::VSEXT_VF4, RISCV::VSEXT_VF8};
2103 unsigned ZExtOp[] = {RISCV::VZEXT_VF2, RISCV::VZEXT_VF4, RISCV::VZEXT_VF8};
2106 return getRISCVInstructionCost(
Op, DstLT.second,
CostKind);
2112 unsigned SrcEltSize = SrcLT.second.getScalarSizeInBits();
2113 unsigned DstEltSize = DstLT.second.getScalarSizeInBits();
2117 : RISCV::VFNCVT_F_F_W;
2119 for (; SrcEltSize != DstEltSize;) {
2123 MVT DstMVT = DstLT.second.changeVectorElementType(ElementMVT);
2125 (DstEltSize > SrcEltSize) ? DstEltSize >> 1 : DstEltSize << 1;
2133 unsigned FCVT = IsSigned ? RISCV::VFCVT_RTZ_X_F_V : RISCV::VFCVT_RTZ_XU_F_V;
2135 IsSigned ? RISCV::VFWCVT_RTZ_X_F_V : RISCV::VFWCVT_RTZ_XU_F_V;
2137 IsSigned ? RISCV::VFNCVT_RTZ_X_F_W : RISCV::VFNCVT_RTZ_XU_F_W;
2138 unsigned SrcEltSize = Src->getScalarSizeInBits();
2139 unsigned DstEltSize = Dst->getScalarSizeInBits();
2141 if ((SrcEltSize == 16) &&
2142 (!ST->hasVInstructionsF16() || ((DstEltSize / 2) > SrcEltSize))) {
2148 std::pair<InstructionCost, MVT> VecF32LT =
2151 VecF32LT.first * getRISCVInstructionCost(RISCV::VFWCVT_F_F_V,
2156 if (DstEltSize == SrcEltSize)
2157 Cost += getRISCVInstructionCost(FCVT, DstLT.second,
CostKind);
2158 else if (DstEltSize > SrcEltSize)
2159 Cost += getRISCVInstructionCost(FWCVT, DstLT.second,
CostKind);
2164 MVT VecVT = DstLT.second.changeVectorElementType(ElementVT);
2165 Cost += getRISCVInstructionCost(FNCVT, VecVT,
CostKind);
2166 if ((SrcEltSize / 2) > DstEltSize) {
2177 unsigned FCVT = IsSigned ? RISCV::VFCVT_F_X_V : RISCV::VFCVT_F_XU_V;
2178 unsigned FWCVT = IsSigned ? RISCV::VFWCVT_F_X_V : RISCV::VFWCVT_F_XU_V;
2179 unsigned FNCVT = IsSigned ? RISCV::VFNCVT_F_X_W : RISCV::VFNCVT_F_XU_W;
2180 unsigned SrcEltSize = Src->getScalarSizeInBits();
2181 unsigned DstEltSize = Dst->getScalarSizeInBits();
2184 if ((DstEltSize == 16) &&
2185 (!ST->hasVInstructionsF16() || ((SrcEltSize / 2) > DstEltSize))) {
2191 std::pair<InstructionCost, MVT> VecF32LT =
2194 Cost += VecF32LT.first * getRISCVInstructionCost(RISCV::VFNCVT_F_F_W,
2199 if (DstEltSize == SrcEltSize)
2200 Cost += getRISCVInstructionCost(FCVT, DstLT.second,
CostKind);
2201 else if (DstEltSize > SrcEltSize) {
2202 if ((DstEltSize / 2) > SrcEltSize) {
2206 unsigned Op = IsSigned ? Instruction::SExt : Instruction::ZExt;
2209 Cost += getRISCVInstructionCost(FWCVT, DstLT.second,
CostKind);
2211 Cost += getRISCVInstructionCost(FNCVT, DstLT.second,
CostKind);
2218unsigned RISCVTTIImpl::getEstimatedVLFor(
VectorType *Ty)
const {
2220 const unsigned EltSize =
DL.getTypeSizeInBits(Ty->getElementType());
2221 const unsigned MinSize =
DL.getTypeSizeInBits(Ty).getKnownMinValue();
2236 if (Ty->getScalarSizeInBits() > ST->getELen())
2240 if (Ty->getElementType()->isIntegerTy(1)) {
2244 if (IID == Intrinsic::umax || IID == Intrinsic::smin)
2250 if (IID == Intrinsic::maximum || IID == Intrinsic::minimum) {
2254 case Intrinsic::maximum:
2256 Opcodes = {RISCV::VFREDMAX_VS, RISCV::VFMV_F_S};
2258 Opcodes = {RISCV::VMFNE_VV, RISCV::VCPOP_M, RISCV::VFREDMAX_VS,
2273 case Intrinsic::minimum:
2275 Opcodes = {RISCV::VFREDMIN_VS, RISCV::VFMV_F_S};
2277 Opcodes = {RISCV::VMFNE_VV, RISCV::VCPOP_M, RISCV::VFREDMIN_VS,
2283 const unsigned EltTyBits =
DL.getTypeSizeInBits(DstTy);
2292 return ExtraCost + getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2301 case Intrinsic::smax:
2302 SplitOp = RISCV::VMAX_VV;
2303 Opcodes = {RISCV::VREDMAX_VS, RISCV::VMV_X_S};
2305 case Intrinsic::smin:
2306 SplitOp = RISCV::VMIN_VV;
2307 Opcodes = {RISCV::VREDMIN_VS, RISCV::VMV_X_S};
2309 case Intrinsic::umax:
2310 SplitOp = RISCV::VMAXU_VV;
2311 Opcodes = {RISCV::VREDMAXU_VS, RISCV::VMV_X_S};
2313 case Intrinsic::umin:
2314 SplitOp = RISCV::VMINU_VV;
2315 Opcodes = {RISCV::VREDMINU_VS, RISCV::VMV_X_S};
2317 case Intrinsic::maxnum:
2318 SplitOp = RISCV::VFMAX_VV;
2319 Opcodes = {RISCV::VFREDMAX_VS, RISCV::VFMV_F_S};
2321 case Intrinsic::minnum:
2322 SplitOp = RISCV::VFMIN_VV;
2323 Opcodes = {RISCV::VFREDMIN_VS, RISCV::VFMV_F_S};
2328 (LT.first > 1) ? (LT.first - 1) *
2329 getRISCVInstructionCost(SplitOp, LT.second,
CostKind)
2331 return SplitCost + getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2336 std::optional<FastMathFlags> FMF,
2342 if (Ty->getScalarSizeInBits() > ST->getELen())
2345 int ISD = TLI->InstructionOpcodeToISD(Opcode);
2353 Type *ElementTy = Ty->getElementType();
2358 if (LT.second == MVT::v1i1)
2359 return getRISCVInstructionCost(RISCV::VFIRST_M, LT.second,
CostKind) +
2377 return ((LT.first > 2) ? (LT.first - 2) : 0) *
2378 getRISCVInstructionCost(RISCV::VMAND_MM, LT.second,
CostKind) +
2379 getRISCVInstructionCost(RISCV::VMNAND_MM, LT.second,
CostKind) +
2380 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind) +
2389 return (LT.first - 1) *
2390 getRISCVInstructionCost(RISCV::VMXOR_MM, LT.second,
CostKind) +
2391 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind) + 1;
2399 return (LT.first - 1) *
2400 getRISCVInstructionCost(RISCV::VMOR_MM, LT.second,
CostKind) +
2401 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind) +
2414 SplitOp = RISCV::VADD_VV;
2415 Opcodes = {RISCV::VMV_S_X, RISCV::VREDSUM_VS, RISCV::VMV_X_S};
2418 SplitOp = RISCV::VOR_VV;
2419 Opcodes = {RISCV::VREDOR_VS, RISCV::VMV_X_S};
2422 SplitOp = RISCV::VXOR_VV;
2423 Opcodes = {RISCV::VMV_S_X, RISCV::VREDXOR_VS, RISCV::VMV_X_S};
2426 SplitOp = RISCV::VAND_VV;
2427 Opcodes = {RISCV::VREDAND_VS, RISCV::VMV_X_S};
2431 if ((LT.second.getScalarType() == MVT::f16 && !ST->hasVInstructionsF16()) ||
2432 LT.second.getScalarType() == MVT::bf16)
2436 for (
unsigned i = 0; i < LT.first.getValue(); i++)
2439 return getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2441 SplitOp = RISCV::VFADD_VV;
2442 Opcodes = {RISCV::VFMV_S_F, RISCV::VFREDUSUM_VS, RISCV::VFMV_F_S};
2447 (LT.first > 1) ? (LT.first - 1) *
2448 getRISCVInstructionCost(SplitOp, LT.second,
CostKind)
2450 return SplitCost + getRISCVInstructionCost(Opcodes, LT.second,
CostKind);
2454 unsigned Opcode,
bool IsUnsigned,
Type *ResTy,
VectorType *ValTy,
2465 if (Opcode != Instruction::Add && Opcode != Instruction::FAdd)
2471 if (IsUnsigned && Opcode == Instruction::Add &&
2472 LT.second.isFixedLengthVectorOf(MVT::i1)) {
2476 getRISCVInstructionCost(RISCV::VCPOP_M, LT.second,
CostKind);
2483 return (LT.first - 1) +
2490 assert(OpInfo.isConstant() &&
"non constant operand?");
2497 if (OpInfo.isUniform())
2503 return getConstantPoolLoadCost(Ty,
CostKind);
2512 EVT VT = TLI->getValueType(
DL, Src,
true);
2514 if (VT == MVT::Other ||
2520 if (Opcode == Instruction::Store && OpInfo.isConstant())
2535 if (Src->
isVectorTy() && LT.second.isVector() &&
2537 LT.second.getSizeInBits()))
2547 if (ST->hasVInstructions() && LT.second.isVector() &&
2549 BaseCost *= TLI->getLMULCost(LT.second);
2550 return Cost + BaseCost;
2559 Op1Info, Op2Info,
I);
2563 Op1Info, Op2Info,
I);
2568 Op1Info, Op2Info,
I);
2570 auto GetConstantMatCost =
2572 if (OpInfo.isUniform())
2577 return getConstantPoolLoadCost(ValTy,
CostKind);
2582 ConstantMatCost += GetConstantMatCost(Op1Info);
2584 ConstantMatCost += GetConstantMatCost(Op2Info);
2587 if (Opcode == Instruction::Select && LT.second.isVector()) {
2588 if (CondTy->isVectorTy()) {
2593 return ConstantMatCost +
2595 getRISCVInstructionCost(
2596 {RISCV::VMANDN_MM, RISCV::VMAND_MM, RISCV::VMOR_MM},
2600 return ConstantMatCost +
2601 LT.first * getRISCVInstructionCost(RISCV::VMERGE_VVM, LT.second,
2611 MVT InterimVT = LT.second.changeVectorElementType(MVT::i8);
2612 return ConstantMatCost +
2614 getRISCVInstructionCost({RISCV::VMV_V_X, RISCV::VMSNE_VI},
2616 LT.first * getRISCVInstructionCost(
2617 {RISCV::VMANDN_MM, RISCV::VMAND_MM, RISCV::VMOR_MM},
2624 return ConstantMatCost +
2625 LT.first * getRISCVInstructionCost(
2626 {RISCV::VMV_V_X, RISCV::VMSNE_VI, RISCV::VMERGE_VVM},
2630 if ((Opcode == Instruction::ICmp) && ValTy->
isVectorTy() &&
2634 return ConstantMatCost + LT.first * getRISCVInstructionCost(RISCV::VMSLT_VV,
2639 if ((Opcode == Instruction::FCmp) && ValTy->
isVectorTy() &&
2644 return ConstantMatCost +
2645 getRISCVInstructionCost(RISCV::VMXOR_MM, LT.second,
CostKind);
2655 Op1Info, Op2Info,
I);
2664 return ConstantMatCost +
2665 LT.first * getRISCVInstructionCost(
2666 {RISCV::VMFLT_VV, RISCV::VMFLT_VV, RISCV::VMOR_MM},
2673 return ConstantMatCost +
2675 getRISCVInstructionCost({RISCV::VMFLT_VV, RISCV::VMNAND_MM},
2684 return ConstantMatCost +
2686 getRISCVInstructionCost(RISCV::VMFLT_VV, LT.second,
CostKind);
2699 return match(U, m_Select(m_Specific(I), m_Value(), m_Value())) &&
2700 U->getType()->isIntegerTy() &&
2701 !isa<ConstantData>(U->getOperand(1)) &&
2702 !isa<ConstantData>(U->getOperand(2));
2710 Op1Info, Op2Info,
I);
2717 return Opcode == Instruction::PHI ? 0 : 1;
2734 if (Opcode != Instruction::ExtractElement &&
2735 Opcode != Instruction::InsertElement)
2741 if (Opcode == Instruction::InsertElement &&
2742 VIC == TTI::VectorInstrContext::SplatOpFolded &&
2743 ST->sinkSplatOperands() && Index == 0)
2750 if (!LT.second.isVector()) {
2760 auto NumElems = FixedVecTy->getNumElements();
2766 return Opcode == Instruction::ExtractElement
2767 ? StoreCost * NumElems + LoadCost
2768 : (StoreCost + LoadCost) * NumElems + StoreCost;
2772 if (LT.second.isScalableVector() && !LT.first.isValid())
2780 if (Opcode == Instruction::ExtractElement) {
2786 return ExtendCost + ExtractCost;
2796 return ExtendCost + InsertCost + TruncCost;
2803 if (LT.second.isFloatingPoint())
2804 MoveOpc = Opcode == Instruction::InsertElement ? RISCV::VFMV_S_F
2808 Opcode == Instruction::InsertElement ? RISCV::VMV_S_X : RISCV::VMV_X_S;
2810 getRISCVInstructionCost(MoveOpc, LT.second,
CostKind);
2812 InstructionCost SlideCost = Opcode == Instruction::InsertElement ? 2 : 1;
2817 if (LT.second.isFixedLengthVector()) {
2818 unsigned Width = LT.second.getVectorNumElements();
2819 Index = Index % Width;
2824 if (
auto VLEN = ST->getRealVLen()) {
2825 unsigned EltSize = LT.second.getScalarSizeInBits();
2826 unsigned M1Max = *VLEN / EltSize;
2827 Index = Index % M1Max;
2833 else if (Opcode == Instruction::InsertElement)
2841 ((Index == -1U) || (Index >= LT.second.getVectorMinNumElements() &&
2842 LT.second.isScalableVector()))) {
2844 Align VecAlign =
DL.getPrefTypeAlign(Val);
2845 Align SclAlign =
DL.getPrefTypeAlign(ScalarType);
2850 if (Opcode == Instruction::ExtractElement)
2886 Opcode == Instruction::InsertElement
2887 ? getRISCVInstructionCost({RISCV::VSLIDE1DOWN_VX,
2888 RISCV::VSLIDE1DOWN_VX,
2889 RISCV::VSLIDEUP_VX},
2891 : getRISCVInstructionCost({RISCV::VSLIDEDOWN_VX, RISCV::VMV_X_S,
2892 RISCV::VSRL_VX, RISCV::VMV_X_S},
2895 return BaseCost + SlideCost;
2901 unsigned Index)
const {
2910 assert(Index < EC.getKnownMinValue() &&
"Unexpected reverse index");
2912 EC.getKnownMinValue() - 1 - Index,
nullptr,
2921std::optional<InstructionCost>
2927 if ((Opcode == Instruction::UDiv || Opcode == Instruction::URem) &&
2929 if (Opcode == Instruction::UDiv)
2936 return std::nullopt;
2958 if (std::optional<InstructionCost> CombinedCost =
2960 Op2Info, Args, CtxI))
2961 return *CombinedCost;
2965 unsigned ISDOpcode = TLI->InstructionOpcodeToISD(Opcode);
2968 if (!LT.second.isVector()) {
2978 if (TLI->isOperationLegalOrPromote(ISDOpcode, LT.second))
2979 if (
const auto *Entry =
CostTableLookup(DivTbl, ISDOpcode, LT.second))
2980 return Entry->Cost * LT.first;
2989 if ((LT.second.getVectorElementType() == MVT::f16 ||
2990 LT.second.getVectorElementType() == MVT::bf16) &&
2991 TLI->getOperationAction(ISDOpcode, LT.second) ==
2993 MVT PromotedVT = TLI->getTypeToPromoteTo(ISDOpcode, LT.second);
2997 CastCost += LT.first * Args.size() *
3005 LT.second = PromotedVT;
3008 auto getConstantMatCost =
3018 return getConstantPoolLoadCost(Ty,
CostKind);
3024 ConstantMatCost += getConstantMatCost(0, Op1Info);
3026 ConstantMatCost += getConstantMatCost(1, Op2Info);
3029 switch (ISDOpcode) {
3032 Op = RISCV::VADD_VV;
3037 Op = RISCV::VSLL_VV;
3042 Op = (Ty->getScalarSizeInBits() == 1) ? RISCV::VMAND_MM : RISCV::VAND_VV;
3047 Op = RISCV::VMUL_VV;
3051 Op = RISCV::VDIV_VV;
3055 Op = RISCV::VREM_VV;
3059 Op = RISCV::VFADD_VV;
3062 Op = RISCV::VFMUL_VV;
3065 Op = RISCV::VFDIV_VV;
3068 Op = RISCV::VFSGNJN_VV;
3073 return CastCost + ConstantMatCost +
3082 if (Ty->isFPOrFPVectorTy())
3084 return CastCost + ConstantMatCost + LT.first *
InstrCost;
3107 if (Info.isSameBase() && V !=
Base) {
3108 if (
GEP->hasAllConstantIndices())
3114 unsigned Stride =
DL.getTypeStoreSize(AccessTy);
3115 if (Info.isUnitStride() &&
3121 GEP->getType()->getPointerAddressSpace()))
3124 {TTI::OK_AnyValue, TTI::OP_None},
3125 {TTI::OK_AnyValue, TTI::OP_None}, {});
3142 if (ST->enableDefaultUnroll())
3152 if (L->getHeader()->getParent()->hasOptSize())
3156 L->getExitingBlocks(ExitingBlocks);
3158 <<
"Blocks: " << L->getNumBlocks() <<
"\n"
3159 <<
"Exit blocks: " << ExitingBlocks.
size() <<
"\n");
3163 if (ExitingBlocks.
size() > 2)
3168 if (L->getNumBlocks() > 4)
3176 for (
auto *BB : L->getBlocks()) {
3177 for (
auto &
I : *BB) {
3181 if (IsVectorized && (
I.getType()->isVectorTy() ||
3183 return V->getType()->isVectorTy();
3222 bool HasMask =
false;
3225 bool IsWrite) -> int64_t {
3226 if (
auto *TarExtTy =
3228 return TarExtTy->getIntParameter(0);
3234 case Intrinsic::riscv_vle_mask:
3235 case Intrinsic::riscv_vse_mask:
3236 case Intrinsic::riscv_vlseg2_mask:
3237 case Intrinsic::riscv_vlseg3_mask:
3238 case Intrinsic::riscv_vlseg4_mask:
3239 case Intrinsic::riscv_vlseg5_mask:
3240 case Intrinsic::riscv_vlseg6_mask:
3241 case Intrinsic::riscv_vlseg7_mask:
3242 case Intrinsic::riscv_vlseg8_mask:
3243 case Intrinsic::riscv_vsseg2_mask:
3244 case Intrinsic::riscv_vsseg3_mask:
3245 case Intrinsic::riscv_vsseg4_mask:
3246 case Intrinsic::riscv_vsseg5_mask:
3247 case Intrinsic::riscv_vsseg6_mask:
3248 case Intrinsic::riscv_vsseg7_mask:
3249 case Intrinsic::riscv_vsseg8_mask:
3252 case Intrinsic::riscv_vle:
3253 case Intrinsic::riscv_vse:
3254 case Intrinsic::riscv_vlseg2:
3255 case Intrinsic::riscv_vlseg3:
3256 case Intrinsic::riscv_vlseg4:
3257 case Intrinsic::riscv_vlseg5:
3258 case Intrinsic::riscv_vlseg6:
3259 case Intrinsic::riscv_vlseg7:
3260 case Intrinsic::riscv_vlseg8:
3261 case Intrinsic::riscv_vsseg2:
3262 case Intrinsic::riscv_vsseg3:
3263 case Intrinsic::riscv_vsseg4:
3264 case Intrinsic::riscv_vsseg5:
3265 case Intrinsic::riscv_vsseg6:
3266 case Intrinsic::riscv_vsseg7:
3267 case Intrinsic::riscv_vsseg8: {
3284 Ty = TarExtTy->getTypeParameter(0U);
3289 const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
3290 unsigned VLIndex = RVVIInfo->VLOperand;
3291 unsigned PtrOperandNo = VLIndex - 1 - HasMask;
3299 unsigned SegNum = getSegNum(Inst, PtrOperandNo, IsWrite);
3302 unsigned ElemSize = Ty->getScalarSizeInBits();
3306 Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty,
3307 Alignment, Mask, EVL);
3310 case Intrinsic::riscv_vlse_mask:
3311 case Intrinsic::riscv_vsse_mask:
3312 case Intrinsic::riscv_vlsseg2_mask:
3313 case Intrinsic::riscv_vlsseg3_mask:
3314 case Intrinsic::riscv_vlsseg4_mask:
3315 case Intrinsic::riscv_vlsseg5_mask:
3316 case Intrinsic::riscv_vlsseg6_mask:
3317 case Intrinsic::riscv_vlsseg7_mask:
3318 case Intrinsic::riscv_vlsseg8_mask:
3319 case Intrinsic::riscv_vssseg2_mask:
3320 case Intrinsic::riscv_vssseg3_mask:
3321 case Intrinsic::riscv_vssseg4_mask:
3322 case Intrinsic::riscv_vssseg5_mask:
3323 case Intrinsic::riscv_vssseg6_mask:
3324 case Intrinsic::riscv_vssseg7_mask:
3325 case Intrinsic::riscv_vssseg8_mask:
3328 case Intrinsic::riscv_vlse:
3329 case Intrinsic::riscv_vsse:
3330 case Intrinsic::riscv_vlsseg2:
3331 case Intrinsic::riscv_vlsseg3:
3332 case Intrinsic::riscv_vlsseg4:
3333 case Intrinsic::riscv_vlsseg5:
3334 case Intrinsic::riscv_vlsseg6:
3335 case Intrinsic::riscv_vlsseg7:
3336 case Intrinsic::riscv_vlsseg8:
3337 case Intrinsic::riscv_vssseg2:
3338 case Intrinsic::riscv_vssseg3:
3339 case Intrinsic::riscv_vssseg4:
3340 case Intrinsic::riscv_vssseg5:
3341 case Intrinsic::riscv_vssseg6:
3342 case Intrinsic::riscv_vssseg7:
3343 case Intrinsic::riscv_vssseg8: {
3360 Ty = TarExtTy->getTypeParameter(0U);
3365 const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
3366 unsigned VLIndex = RVVIInfo->VLOperand;
3367 unsigned PtrOperandNo = VLIndex - 2 - HasMask;
3376 unsigned PointerAlign = Alignment.valueOrOne().value();
3379 Alignment =
Align(1);
3386 unsigned SegNum = getSegNum(Inst, PtrOperandNo, IsWrite);
3389 unsigned ElemSize = Ty->getScalarSizeInBits();
3393 Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty,
3394 Alignment, Mask, EVL, Stride);
3397 case Intrinsic::riscv_vloxei_mask:
3398 case Intrinsic::riscv_vluxei_mask:
3399 case Intrinsic::riscv_vsoxei_mask:
3400 case Intrinsic::riscv_vsuxei_mask:
3401 case Intrinsic::riscv_vloxseg2_mask:
3402 case Intrinsic::riscv_vloxseg3_mask:
3403 case Intrinsic::riscv_vloxseg4_mask:
3404 case Intrinsic::riscv_vloxseg5_mask:
3405 case Intrinsic::riscv_vloxseg6_mask:
3406 case Intrinsic::riscv_vloxseg7_mask:
3407 case Intrinsic::riscv_vloxseg8_mask:
3408 case Intrinsic::riscv_vluxseg2_mask:
3409 case Intrinsic::riscv_vluxseg3_mask:
3410 case Intrinsic::riscv_vluxseg4_mask:
3411 case Intrinsic::riscv_vluxseg5_mask:
3412 case Intrinsic::riscv_vluxseg6_mask:
3413 case Intrinsic::riscv_vluxseg7_mask:
3414 case Intrinsic::riscv_vluxseg8_mask:
3415 case Intrinsic::riscv_vsoxseg2_mask:
3416 case Intrinsic::riscv_vsoxseg3_mask:
3417 case Intrinsic::riscv_vsoxseg4_mask:
3418 case Intrinsic::riscv_vsoxseg5_mask:
3419 case Intrinsic::riscv_vsoxseg6_mask:
3420 case Intrinsic::riscv_vsoxseg7_mask:
3421 case Intrinsic::riscv_vsoxseg8_mask:
3422 case Intrinsic::riscv_vsuxseg2_mask:
3423 case Intrinsic::riscv_vsuxseg3_mask:
3424 case Intrinsic::riscv_vsuxseg4_mask:
3425 case Intrinsic::riscv_vsuxseg5_mask:
3426 case Intrinsic::riscv_vsuxseg6_mask:
3427 case Intrinsic::riscv_vsuxseg7_mask:
3428 case Intrinsic::riscv_vsuxseg8_mask:
3431 case Intrinsic::riscv_vloxei:
3432 case Intrinsic::riscv_vluxei:
3433 case Intrinsic::riscv_vsoxei:
3434 case Intrinsic::riscv_vsuxei:
3435 case Intrinsic::riscv_vloxseg2:
3436 case Intrinsic::riscv_vloxseg3:
3437 case Intrinsic::riscv_vloxseg4:
3438 case Intrinsic::riscv_vloxseg5:
3439 case Intrinsic::riscv_vloxseg6:
3440 case Intrinsic::riscv_vloxseg7:
3441 case Intrinsic::riscv_vloxseg8:
3442 case Intrinsic::riscv_vluxseg2:
3443 case Intrinsic::riscv_vluxseg3:
3444 case Intrinsic::riscv_vluxseg4:
3445 case Intrinsic::riscv_vluxseg5:
3446 case Intrinsic::riscv_vluxseg6:
3447 case Intrinsic::riscv_vluxseg7:
3448 case Intrinsic::riscv_vluxseg8:
3449 case Intrinsic::riscv_vsoxseg2:
3450 case Intrinsic::riscv_vsoxseg3:
3451 case Intrinsic::riscv_vsoxseg4:
3452 case Intrinsic::riscv_vsoxseg5:
3453 case Intrinsic::riscv_vsoxseg6:
3454 case Intrinsic::riscv_vsoxseg7:
3455 case Intrinsic::riscv_vsoxseg8:
3456 case Intrinsic::riscv_vsuxseg2:
3457 case Intrinsic::riscv_vsuxseg3:
3458 case Intrinsic::riscv_vsuxseg4:
3459 case Intrinsic::riscv_vsuxseg5:
3460 case Intrinsic::riscv_vsuxseg6:
3461 case Intrinsic::riscv_vsuxseg7:
3462 case Intrinsic::riscv_vsuxseg8: {
3479 Ty = TarExtTy->getTypeParameter(0U);
3484 const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
3485 unsigned VLIndex = RVVIInfo->VLOperand;
3486 unsigned PtrOperandNo = VLIndex - 2 - HasMask;
3499 unsigned SegNum = getSegNum(Inst, PtrOperandNo, IsWrite);
3502 unsigned ElemSize = Ty->getScalarSizeInBits();
3507 Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty,
3508 Align(1), Mask, EVL,
3517 if (Ty->isVectorTy()) {
3520 if ((EltTy->
isHalfTy() && !ST->hasVInstructionsF16()) ||
3526 if (
Size.isScalable() && ST->hasVInstructions())
3529 if (ST->useRVVForFixedLengthVectors())
3537 if (std::optional<unsigned> MaxVF = ST->getCLOpts().v_slp_max_vf)
3549 return std::max<unsigned>(1U, RegWidth.
getFixedValue() / ElemWidth);
3553 return ST->getCLOpts().v_min_trip_count;
3557 return ST->enableUnalignedVectorMem();
3563 if (ST->hasVendorXCVmem() && !ST->is64Bit())
3585 Align Alignment)
const {
3595 if (VTy->getElementType()->isIntegerTy(8)) {
3596 uint64_t MaxEltCount = VTy->getElementCount().getKnownMinValue();
3597 if (VTy->isScalableTy())
3600 if (MaxEltCount > 256)
3609 Align Alignment)
const {
3616 if (!ST->hasVInstructions() || !ST->hasOptimizedZeroStrideLoad())
3619 return TLI->isLegalElementTypeForRVV(TLI->getValueType(
DL, ElementTy));
3628 const Instruction &
I,
bool &AllowPromotionWithoutCommonHeader)
const {
3629 bool Considerable =
false;
3630 AllowPromotionWithoutCommonHeader =
false;
3633 Type *ConsideredSExtType =
3635 if (
I.getType() != ConsideredSExtType)
3639 for (
const User *U :
I.users()) {
3641 Considerable =
true;
3645 if (GEPInst->getNumOperands() > 2) {
3646 AllowPromotionWithoutCommonHeader =
true;
3651 return Considerable;
3656 case Instruction::Add:
3657 case Instruction::Sub:
3658 case Instruction::Mul:
3659 case Instruction::And:
3660 case Instruction::Or:
3661 case Instruction::Xor:
3662 case Instruction::FAdd:
3663 case Instruction::FSub:
3664 case Instruction::FMul:
3665 case Instruction::FDiv:
3666 case Instruction::ICmp:
3667 case Instruction::FCmp:
3669 case Instruction::Shl:
3670 case Instruction::LShr:
3671 case Instruction::AShr:
3672 case Instruction::UDiv:
3673 case Instruction::SDiv:
3674 case Instruction::URem:
3675 case Instruction::SRem:
3676 case Instruction::Select:
3677 return Operand == 1;
3684 if (!
I->getType()->isVectorTy() || !ST->hasVInstructions())
3694 switch (
II->getIntrinsicID()) {
3695 case Intrinsic::fma:
3696 case Intrinsic::fmuladd:
3697 return Operand == 0 || Operand == 1;
3698 case Intrinsic::vp_udiv:
3699 case Intrinsic::vp_sdiv:
3700 case Intrinsic::vp_urem:
3701 case Intrinsic::vp_srem:
3702 case Intrinsic::ssub_sat:
3703 case Intrinsic::usub_sat:
3704 return Operand == 1;
3706 case Intrinsic::smin:
3707 case Intrinsic::umin:
3708 case Intrinsic::smax:
3709 case Intrinsic::umax:
3710 case Intrinsic::sadd_sat:
3711 case Intrinsic::uadd_sat:
3712 return Operand == 0 || Operand == 1;
3721 GatherUseOps)
const {
3722 if (Scalars.
empty() || !ST->hasVInstructions() || !ST->sinkSplatOperands() ||
3727 if (SplatIt == Scalars.
end() || (*SplatIt)->getType()->isIntegerTy(1) ||
3733 if (!GatherUseOps(UserOps) || UserOps.
empty())
3752 if (
I->isBitwiseLogicOp()) {
3753 if (!
I->getType()->isVectorTy()) {
3754 if (ST->hasStdExtZbb() || ST->hasStdExtZbkb()) {
3755 for (
auto &
Op :
I->operands()) {
3763 }
else if (
I->getOpcode() == Instruction::And && ST->hasStdExtZvkb()) {
3764 for (
auto &
Op :
I->operands()) {
3776 Ops.push_back(&Not);
3777 Ops.push_back(&InsertElt);
3785 if (!
I->getType()->isVectorTy() || !ST->hasVInstructions())
3793 if (!ST->sinkSplatOperands())
3796 for (
auto OpIdx :
enumerate(
I->operands())) {
3816 for (
Use &U :
Op->uses()) {
3823 Use *InsertEltUse = &
Op->getOperandUse(0);
3826 Ops.push_back(&InsertElt->getOperandUse(1));
3827 Ops.push_back(InsertEltUse);
3828 Ops.push_back(&OpIdx.value());
3837 if (!ST->hasStdExtZbb() && !ST->hasStdExtZbkb() && !IsZeroCmp)
3840 Options.AllowOverlappingLoads =
true;
3841 Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize);
3843 if (ST->is64Bit()) {
3844 Options.LoadSizes = {8, 4, 2, 1};
3845 Options.AllowedTailExpansions = {3, 5, 6};
3847 Options.LoadSizes = {4, 2, 1};
3848 Options.AllowedTailExpansions = {3};
3851 if (IsZeroCmp && ST->hasVInstructions()) {
3852 unsigned VLenB = ST->getRealMinVLen() / 8;
3855 unsigned MinSize = ST->getXLen() / 8 + 1;
3856 unsigned MaxSize = VLenB * 8;
3865 if (ST->getCLOpts().or_like_select) {
3870 if (
I->getOpcode() == Instruction::Or &&
3874 if (
I->getOpcode() == Instruction::Add ||
3875 I->getOpcode() == Instruction::Sub)
3893std::optional<Instruction *>
3899 if (
is_contained({Intrinsic::riscv_vsetvli, Intrinsic::riscv_vsetvlimax},
3900 II.getIntrinsicID())) {
3903 if (!ST->hasVInstructions())
3906 bool HasAVL =
II.getIntrinsicID() == Intrinsic::riscv_vsetvli;
3907 unsigned Offset = HasAVL ? 1 : 0;
3908 unsigned BitWidth =
II.getType()->getIntegerBitWidth();
3933 Value *AVL =
II.getArgOperand(0);
3962 II.getRange().value_or(ConstantRange::getFull(
BitWidth));
3964 if (NewRange != OldRange) {
3965 II.addRangeRetAttr(NewRange);
3975 if (
II.user_empty())
3980 const APInt *Scalar;
3985 return U->getType() == TargetVecTy && match(U, m_BitCast(m_Value()));
3989 unsigned TargetEltBW =
DL.getTypeSizeInBits(TargetVecTy->getElementType());
3990 unsigned SourceEltBW =
DL.getTypeSizeInBits(SourceVecTy->getElementType());
3991 if (TargetEltBW % SourceEltBW)
3993 unsigned TargetScale = TargetEltBW / SourceEltBW;
3994 if (VL % TargetScale || TargetScale == 1)
3996 Type *VLTy =
II.getOperand(2)->getType();
3997 ElementCount SourceEC = SourceVecTy->getElementCount();
3998 unsigned NewEltBW = SourceEltBW * TargetScale;
4000 !
DL.fitsInLegalInteger(NewEltBW))
4003 if (!TLI->isLegalElementTypeForRVV(TLI->getValueType(
DL, NewEltTy)))
4007 assert(SourceVecTy->canLosslesslyBitCastTo(RetTy) &&
4008 "Lossless bitcast between types expected");
4014 RetTy, Intrinsic::riscv_vmv_v_x,
4015 {PoisonValue::get(RetTy), ConstantInt::get(NewEltTy, NewScalar),
4016 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.
bool empty() const
Check if the array is empty.
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 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
InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Opd1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Opd2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr) const override
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 getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, TTI::TargetCostKind CostKind, ArrayRef< int > Mask, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost 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 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)
This is the shared class of boolean and integer constants.
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)
static FixedVectorType * getHalfElementsVectorType(FixedVectorType *VTy)
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.
bool isScalableVector() const
Return true if this is a vector value type where the runtime length is machine dependent.
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
ElementCount getVectorElementCount() 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 getHalfNumVectorElementsVT() const
Return a VT for a vector type with the same element type but half the number of elements.
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
const Value * getStrideVal() 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
bool shouldCopyAttributeWhenOutliningFrom(const Function *Caller, const Attribute &Attr) const override
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
bool isLegalMaskedExpandLoad(Type *DataType, Align Alignment) const override
InstructionCost getStridedMemoryOpCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const
bool isLegalMaskedLoadStore(Type *DataType, Align Alignment) const
TargetTransformInfo::VectorInstrContext getBuildVectorContextHint(ArrayRef< int > Mask, ArrayRef< Value * > Scalars, function_ref< bool(SmallVectorImpl< TargetTransformInfo::BuildVectorUseOp > &)> GatherUseOps) const override
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 getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, TTI::TargetCostKind CostKind, ArrayRef< int > Mask, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getStoreImmCost(Type *VecTy, TTI::OperandValueInfo OpInfo, TTI::TargetCostKind CostKind) const
Return the cost of materializing an immediate for a value operand of a store instruction.
bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info) const override
InstructionCost getCostOfKeepingLiveOverCall(ArrayRef< Type * > Tys) const override
bool hasActiveVectorLength() const override
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
InstructionCost getIndexedVectorInstrCostFromEnd(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index) const override
void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, TTI::UnrollingPreferences &UP, OptimizationRemarkEmitter *ORE) const override
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
std::optional< InstructionCost > getCombinedArithmeticInstructionCost(unsigned ISDOpcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Opd1Info, TTI::OperandValueInfo Opd2Info, ArrayRef< const Value * > Args, const Instruction *CtxI) const
Check to see if this instruction is expected to be combined to a simpler operation during/before lowe...
InstructionCost getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const override
Get memory intrinsic cost based on arguments.
InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr) const override
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 isZeroEltSplatMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses all elements with the same value as the first element of exa...
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...
static LLVM_ABI IntegerType * getInt16Ty(LLVMContext &C)
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 isKnownEven() const
A return value of true indicates we know at compile time that the number of elements (vscale * Min) i...
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...
An efficient, type-erasing, non-owning reference to a callable.
#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
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.
@ None
The instruction is not folded.
@ BinaryOp
One of the operands is a binary op.
@ SplatOpFolded
All of the value's users support splatting the value.
auto adjacent_find(R &&Range)
Provide wrappers to std::adjacent_find which finds the first pair of adjacent elements that are equal...
bool isPairEven(const std::array< std::pair< int, int >, 2 > &SrcInfo, ArrayRef< int > Mask, unsigned &Factor)
Given a shuffle which can be represented as a pair of two slides, see if it is a pair-even idiom.
bool isPairOdd(const std::array< std::pair< int, int >, 2 > &SrcInfo, ArrayRef< int > Mask, unsigned &Factor)
Given a shuffle which can be represented as a pair of two slides, see if it is a pair-odd idiom.
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...
auto dyn_cast_or_null(const Y &Val)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
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.
auto find_if_not(R &&Range, UnaryPredicate P)
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.
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
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