28#include "llvm/IR/IntrinsicsAMDGPU.h"
36#define DEBUG_TYPE "AMDGPUtti"
40struct AMDGPUImageDMaskIntrinsic {
44#define GET_AMDGPUImageDMaskIntrinsicTable_IMPL
45#include "AMDGPUGenSearchableTables.inc"
56 "nans handled separately");
74 bool AllowI16SExt =
false) {
75 Type *VTy = V.getType();
84 APFloat FloatValue(ConstFloat->getValueAPF());
85 bool LosesInfo =
true;
94 APInt IntValue(ConstInt->getValue());
103 Value *CastCandidate;
110 if (!IsExt && !IsFloat && AllowI16SExt)
123 Type *VTy = V.getType();
132 return Builder.CreateExtractElement(VecCast->
getOperand(0), Idx);
156 Func(Args, OverloadTys);
172 bool RemoveOldIntr = &OldIntr != &InstToReplace;
181static std::optional<Instruction *>
186 if (
const auto *LZMappingInfo =
188 if (
auto *ConstantLod =
190 if (ConstantLod->isZero() || ConstantLod->isNegative()) {
195 II,
II, NewImageDimIntr->
Intr, IC, [&](
auto &Args,
auto &ArgTys) {
196 Args.erase(Args.begin() + ImageDimIntr->LodIndex);
203 if (
const auto *MIPMappingInfo =
205 if (
auto *ConstantMip =
207 if (ConstantMip->isZero()) {
212 II,
II, NewImageDimIntr->
Intr, IC, [&](
auto &Args,
auto &ArgTys) {
213 Args.erase(Args.begin() + ImageDimIntr->MipIndex);
220 if (
const auto *BiasMappingInfo =
222 if (
auto *ConstantBias =
224 if (ConstantBias->isZero()) {
229 II,
II, NewImageDimIntr->
Intr, IC, [&](
auto &Args,
auto &ArgTys) {
230 Args.erase(Args.begin() + ImageDimIntr->BiasIndex);
231 ArgTys.erase(ArgTys.begin() + ImageDimIntr->BiasTyArg);
238 if (
const auto *OffsetMappingInfo =
240 if (
auto *ConstantOffset =
242 if (ConstantOffset->isZero()) {
245 OffsetMappingInfo->NoOffset, ImageDimIntr->
Dim);
247 II,
II, NewImageDimIntr->
Intr, IC, [&](
auto &Args,
auto &ArgTys) {
248 Args.erase(Args.begin() + ImageDimIntr->OffsetIndex);
255 if (ST->hasD16Images()) {
265 if (
II.hasOneUse()) {
268 if (
User->getOpcode() == Instruction::FPTrunc &&
272 [&](
auto &Args,
auto &ArgTys) {
275 ArgTys[0] = User->getType();
284 bool AllHalfExtracts =
true;
286 for (
User *U :
II.users()) {
288 if (!Ext || !Ext->hasOneUse()) {
289 AllHalfExtracts =
false;
294 if (!Tr || !Tr->getType()->isHalfTy()) {
295 AllHalfExtracts =
false;
302 if (!ExtractTruncPairs.
empty() && AllHalfExtracts) {
313 OverloadTys[0] = HalfVecTy;
316 M, ImageDimIntr->
Intr, OverloadTys);
318 II.mutateType(HalfVecTy);
319 II.setCalledFunction(HalfDecl);
322 for (
auto &[Ext, Tr] : ExtractTruncPairs) {
323 Value *Idx = Ext->getIndexOperand();
325 Builder.SetInsertPoint(Tr);
327 Value *HalfExtract = Builder.CreateExtractElement(&
II, Idx);
330 Tr->replaceAllUsesWith(HalfExtract);
333 for (
auto &[Ext, Tr] : ExtractTruncPairs) {
344 if (!ST->hasA16() && !ST->hasG16())
351 bool FloatCoord =
false;
353 bool OnlyDerivatives =
false;
358 bool AllowI16SExt = !HasSampler;
361 OperandIndex < ImageDimIntr->VAddrEnd; OperandIndex++) {
362 Value *Coord =
II.getOperand(OperandIndex);
365 if (OperandIndex < ImageDimIntr->CoordStart ||
370 OnlyDerivatives =
true;
379 if (!OnlyDerivatives && !ST->hasA16())
380 OnlyDerivatives =
true;
383 if (!OnlyDerivatives && ImageDimIntr->
NumBiasArgs != 0) {
386 "Only image instructions with a sampler can have a bias");
388 OnlyDerivatives =
true;
391 if (OnlyDerivatives && (!ST->hasG16() || ImageDimIntr->
GradientStart ==
399 II,
II,
II.getIntrinsicID(), IC, [&](
auto &Args,
auto &ArgTys) {
400 ArgTys[ImageDimIntr->GradientTyArg] = CoordType;
401 if (!OnlyDerivatives) {
402 ArgTys[ImageDimIntr->CoordTyArg] = CoordType;
405 if (ImageDimIntr->NumBiasArgs != 0)
406 ArgTys[ImageDimIntr->BiasTyArg] = Type::getHalfTy(II.getContext());
412 OperandIndex < EndIndex; OperandIndex++) {
414 convertTo16Bit(*II.getOperand(OperandIndex), IC.Builder);
419 Value *Bias = II.getOperand(ImageDimIntr->BiasIndex);
420 Args[ImageDimIntr->BiasIndex] = convertTo16Bit(*Bias, IC.Builder);
449 Value *Src =
nullptr;
452 if (Src->getType()->isHalfTy())
469 unsigned VWidth = VTy->getNumElements();
472 for (
int i = VWidth - 1; i > 0; --i) {
494 unsigned VWidth = VTy->getNumElements();
500 SVI->getShuffleMask(ShuffleMask);
502 for (
int I = VWidth - 1;
I > 0; --
I) {
503 if (ShuffleMask.empty()) {
554 unsigned LaneArgIdx)
const {
555 unsigned MaskBits = ST->getWavefrontSizeLog2();
562 if (!
Known.isConstant())
569 Value *LaneArg =
II.getArgOperand(LaneArgIdx);
571 ConstantInt::get(LaneArg->
getType(),
Known.getConstant() & DemandedMask);
572 if (MaskedConst != LaneArg) {
573 II.getOperandUse(LaneArgIdx).set(MaskedConst);
585 CallInst *NewCall =
B.CreateCall(&NewCallee,
Ops, OpBundles);
601 if (ST.isWave32() &&
match(V, W32Pred))
603 if (ST.isWave64() &&
match(V, W64Pred))
612 const auto IID =
II.getIntrinsicID();
613 assert(IID == Intrinsic::amdgcn_readlane ||
614 IID == Intrinsic::amdgcn_readfirstlane ||
615 IID == Intrinsic::amdgcn_permlane64);
625 const bool IsReadLane = (IID == Intrinsic::amdgcn_readlane);
629 Value *LaneID =
nullptr;
631 LaneID =
II.getOperand(1);
645 const auto DoIt = [&](
unsigned OpIdx,
649 Ops.push_back(LaneID);
665 return DoIt(0,
II.getCalledFunction());
669 Type *SrcTy = Src->getType();
675 return DoIt(0, Remangled);
683 return DoIt(1,
II.getCalledFunction());
685 return DoIt(0,
II.getCalledFunction());
696 unsigned Depth = 0) {
706 return CI->getZExtValue();
715 std::optional<unsigned>
LHS =
719 std::optional<unsigned>
RHS =
728 return CI ? std::optional<unsigned>(CI->getZExtValue()) : std::nullopt;
736 unsigned WaveSize = ST.getWavefrontSize();
738 for (
unsigned Lane :
seq(WaveSize)) {
740 if (!Val || *Val >= WaveSize)
749template <
unsigned Period>
751 static_assert(
isPowerOf2_32(Period),
"Period must be a power of two");
752 for (
unsigned I = Period,
E = Ids.
size();
I <
E; ++
I)
753 if (Ids[
I] != Ids[
I % Period] + (
I & ~(Period - 1)))
761 for (
unsigned I = 0;
I <
N; ++
I)
777 return Ids[3] << 6 | Ids[2] << 4 | Ids[1] << 2 | Ids[0];
784 for (
unsigned J = 0; J <
N; ++J)
785 if (Ids[J] != (
N - 1) - J)
797 for (
unsigned J = 1; J < 16; ++J)
798 if (Ids[J] != (Ids[0] + J) % 16)
816 unsigned Mask = Ids[0];
819 for (
unsigned J = 0; J < 16; ++J)
820 if (Ids[J] != (Mask ^ J))
830 unsigned Selector = 0;
831 for (
unsigned J = 0; J < 8; ++J)
832 Selector |= Ids[J] << (J * 3);
841 for (
unsigned J = 0; J < 16; ++J)
842 Sel |=
static_cast<uint64_t>(Ids[J] & 0xF) << (J * 4);
849 if (Ids.
size() != 64)
851 for (
unsigned J = 0; J < 64; ++J)
852 if (Ids[J] != (J ^ 32))
863 for (
unsigned J = 0; J < 16; ++J) {
864 if (Ids[J] < 16 || Ids[J] >= 32)
866 if (Ids[J + 16] != Ids[J] - 16)
877static std::optional<unsigned>
886 unsigned AndMask = 0, OrMask = 0, XorMask = 0;
887 for (
unsigned B = 0;
B < 5; ++
B) {
888 unsigned Bit0 = (Ids[0] >>
B) & 1;
889 unsigned Bit1 = (Ids[1u <<
B] >>
B) & 1;
892 XorMask |= Bit0 <<
B;
900 for (
unsigned I :
seq(32u)) {
901 unsigned Expected = ((
I & AndMask) | OrMask) ^ XorMask;
916static std::optional<unsigned>
927 for (
unsigned I = 0;
I < 32; ++
I)
928 if (Ids[
I] != (
I +
N) % 32)
940 return B.CreateIntrinsic(Intrinsic::amdgcn_update_dpp, {Ty},
942 B.getInt32(0xF),
B.getInt32(0xF),
B.getTrue()});
947 return B.CreateIntrinsic(Intrinsic::amdgcn_mov_dpp8, {Val->
getType()},
948 {Val,
B.getInt32(Selector)});
955 return B.CreateIntrinsic(Intrinsic::amdgcn_permlane16, {Ty},
957 B.getInt32(
Hi),
B.getFalse(),
B.getFalse()});
965 return B.CreateIntrinsic(Intrinsic::amdgcn_permlanex16, {Ty},
967 B.getInt32(
Hi),
B.getFalse(),
B.getFalse()});
975 assert(
DL.getTypeSizeInBits(OrigTy) == 32 &&
976 "ds_swizzle only supports 32-bit operands");
980 Src =
B.CreatePtrToInt(Src, I32Ty);
981 else if (OrigTy != I32Ty)
982 Src =
B.CreateBitCast(Src, I32Ty);
983 Value *Result =
B.CreateIntrinsic(Intrinsic::amdgcn_ds_swizzle, {},
986 return B.CreateIntToPtr(Result, OrigTy);
988 return B.CreateBitCast(Result, OrigTy);
994 return B.CreateIntrinsic(Intrinsic::amdgcn_permlane64, {Val->
getType()},
1005 [](
const auto &
E) {
return E.value() ==
E.index(); }))
1029 if (ST.hasDPPRowShare()) {
1034 if (ST.hasDPP() && ST.hasGFX10Insts()) {
1044 if (ST.hasPermlane16Insts()) {
1064 if (ST.hasDsSwizzleRotateMode()) {
1077static std::optional<Instruction *>
1081 if (
DL.getTypeSizeInBits(
II.getType()) != 32)
1082 return std::nullopt;
1084 if (!ST.isWaveSizeKnown())
1085 return std::nullopt;
1087 unsigned WaveSize = ST.getWavefrontSize();
1088 bool IsBpermute =
II.getIntrinsicID() == Intrinsic::amdgcn_ds_bpermute;
1089 Value *Src =
II.getArgOperand(IsBpermute ? 1 : 0);
1090 Value *Index =
II.getArgOperand(IsBpermute ? 0 : 1);
1095 for (
unsigned Lane :
seq(WaveSize)) {
1097 if (!Val || (*Val & 3) || (*Val >> 2) >= WaveSize)
1098 return std::nullopt;
1099 Ids[Lane] = *Val >> 2;
1103 return std::nullopt;
1108 return std::nullopt;
1112std::optional<Instruction *>
1116 case Intrinsic::amdgcn_implicitarg_ptr: {
1117 if (
II.getFunction()->hasFnAttribute(
"amdgpu-no-implicitarg-ptr"))
1119 uint64_t ImplicitArgBytes = ST->getImplicitArgNumBytes(*
II.getFunction());
1122 II.getAttributes().getRetDereferenceableOrNullBytes();
1123 if (CurrentOrNullBytes != 0) {
1126 uint64_t NewBytes = std::max(CurrentOrNullBytes, ImplicitArgBytes);
1129 II.removeRetAttr(Attribute::DereferenceableOrNull);
1133 uint64_t CurrentBytes =
II.getAttributes().getRetDereferenceableBytes();
1134 uint64_t NewBytes = std::max(CurrentBytes, ImplicitArgBytes);
1135 if (NewBytes != CurrentBytes) {
1141 return std::nullopt;
1143 case Intrinsic::amdgcn_rcp: {
1144 Value *Src =
II.getArgOperand(0);
1155 if (
II.isStrictFP())
1159 const APFloat &ArgVal =
C->getValueAPF();
1177 auto IID = SrcCI->getIntrinsicID();
1182 if (IID == Intrinsic::amdgcn_sqrt || IID == Intrinsic::sqrt) {
1192 SrcCI->getModule(), Intrinsic::amdgcn_rsq, {SrcCI->getType()});
1195 II.setFastMathFlags(InnerFMF);
1197 II.setCalledFunction(NewDecl);
1203 case Intrinsic::amdgcn_sqrt:
1204 case Intrinsic::amdgcn_rsq:
1205 case Intrinsic::amdgcn_tanh: {
1206 Value *Src =
II.getArgOperand(0);
1218 if (IID == Intrinsic::amdgcn_sqrt && Src->getType()->isHalfTy()) {
1220 II.getModule(), Intrinsic::sqrt, {II.getType()});
1221 II.setCalledFunction(NewDecl);
1227 case Intrinsic::amdgcn_log:
1228 case Intrinsic::amdgcn_exp2: {
1229 const bool IsLog = IID == Intrinsic::amdgcn_log;
1230 const bool IsExp = IID == Intrinsic::amdgcn_exp2;
1231 Value *Src =
II.getArgOperand(0);
1241 if (
C->isInfinity()) {
1244 if (!
C->isNegative())
1248 if (IsExp &&
C->isNegative())
1252 if (
II.isStrictFP())
1256 Constant *Quieted = ConstantFP::get(Ty,
C->getValue().makeQuiet());
1261 if (
C->isZero() || (
C->getValue().isDenormal() && Ty->isFloatTy())) {
1263 : ConstantFP::get(Ty, 1.0);
1267 if (IsLog &&
C->isNegative())
1275 case Intrinsic::amdgcn_frexp_mant:
1276 case Intrinsic::amdgcn_frexp_exp: {
1277 Value *Src =
II.getArgOperand(0);
1283 if (IID == Intrinsic::amdgcn_frexp_mant) {
1285 II, ConstantFP::get(
II.getContext(), Significand));
1305 case Intrinsic::amdgcn_class: {
1306 Value *Src0 =
II.getArgOperand(0);
1307 Value *Src1 =
II.getArgOperand(1);
1311 II.getModule(), Intrinsic::is_fpclass, Src0->
getType()));
1314 II.setArgOperand(1, ConstantInt::get(Src1->
getType(),
1335 case Intrinsic::amdgcn_cvt_pkrtz: {
1336 auto foldFPTruncToF16RTZ = [](
Value *Arg) ->
Value * {
1349 return ConstantFP::get(HalfTy, Val);
1352 Value *Src =
nullptr;
1354 if (Src->getType()->isHalfTy())
1361 if (
Value *Src0 = foldFPTruncToF16RTZ(
II.getArgOperand(0))) {
1362 if (
Value *Src1 = foldFPTruncToF16RTZ(
II.getArgOperand(1))) {
1372 case Intrinsic::amdgcn_cvt_pknorm_i16:
1373 case Intrinsic::amdgcn_cvt_pknorm_u16:
1374 case Intrinsic::amdgcn_cvt_pk_i16:
1375 case Intrinsic::amdgcn_cvt_pk_u16: {
1376 Value *Src0 =
II.getArgOperand(0);
1377 Value *Src1 =
II.getArgOperand(1);
1389 case Intrinsic::amdgcn_cvt_off_f32_i4: {
1390 Value* Arg =
II.getArgOperand(0);
1404 constexpr size_t ResValsSize = 16;
1405 static constexpr float ResVals[ResValsSize] = {
1406 0.0, 0.0625, 0.125, 0.1875, 0.25, 0.3125, 0.375, 0.4375,
1407 -0.5, -0.4375, -0.375, -0.3125, -0.25, -0.1875, -0.125, -0.0625};
1409 ConstantFP::get(Ty, ResVals[CArg->
getZExtValue() & (ResValsSize - 1)]);
1412 case Intrinsic::amdgcn_ubfe:
1413 case Intrinsic::amdgcn_sbfe: {
1415 Value *Src =
II.getArgOperand(0);
1422 unsigned IntSize = Ty->getIntegerBitWidth();
1427 if ((Width & (IntSize - 1)) == 0) {
1432 if (Width >= IntSize) {
1434 II, 2, ConstantInt::get(CWidth->
getType(), Width & (IntSize - 1)));
1445 ConstantInt::get(COffset->
getType(),
Offset & (IntSize - 1)));
1449 bool Signed = IID == Intrinsic::amdgcn_sbfe;
1451 if (!CWidth || !COffset)
1461 if (
Offset + Width < IntSize) {
1465 RightShift->takeName(&
II);
1472 RightShift->takeName(&
II);
1475 case Intrinsic::amdgcn_exp:
1476 case Intrinsic::amdgcn_exp_row:
1477 case Intrinsic::amdgcn_exp_compr: {
1483 bool IsCompr = IID == Intrinsic::amdgcn_exp_compr;
1485 for (
int I = 0;
I < (IsCompr ? 2 : 4); ++
I) {
1486 if ((!IsCompr && (EnBits & (1 <<
I)) == 0) ||
1487 (IsCompr && ((EnBits & (0x3 << (2 *
I))) == 0))) {
1488 Value *Src =
II.getArgOperand(
I + 2);
1502 case Intrinsic::amdgcn_fmed3: {
1503 Value *Src0 =
II.getArgOperand(0);
1504 Value *Src1 =
II.getArgOperand(1);
1505 Value *Src2 =
II.getArgOperand(2);
1507 for (
Value *Src : {Src0, Src1, Src2}) {
1512 if (
II.isStrictFP())
1549 const APFloat *ConstSrc0 =
nullptr;
1550 const APFloat *ConstSrc1 =
nullptr;
1551 const APFloat *ConstSrc2 =
nullptr;
1556 const bool IsPosInfinity = ConstSrc0 && ConstSrc0->
isPosInfinity();
1576 const bool IsPosInfinity = ConstSrc1 && ConstSrc1->
isPosInfinity();
1599 auto *Quieted = ConstantFP::get(
II.getType(), ConstSrc2->
makeQuiet());
1619 CI->copyFastMathFlags(&
II);
1645 II.setArgOperand(0, Src0);
1646 II.setArgOperand(1, Src1);
1647 II.setArgOperand(2, Src2);
1657 ConstantFP::get(
II.getType(), Result));
1662 if (!ST->hasMed3_16())
1671 IID, {
X->getType()}, {
X,
Y, Z}, &
II,
II.getName());
1679 case Intrinsic::amdgcn_icmp:
1680 case Intrinsic::amdgcn_fcmp: {
1684 bool IsInteger = IID == Intrinsic::amdgcn_icmp;
1691 Value *Src0 =
II.getArgOperand(0);
1692 Value *Src1 =
II.getArgOperand(1);
1719 II.setArgOperand(0, Src1);
1720 II.setArgOperand(1, Src0);
1722 2, ConstantInt::get(CC->
getType(),
static_cast<int>(SwapPred)));
1769 ? Intrinsic::amdgcn_fcmp
1770 : Intrinsic::amdgcn_icmp;
1775 unsigned Width = CmpType->getBitWidth();
1776 unsigned NewWidth = Width;
1784 else if (Width <= 32)
1786 else if (Width <= 64)
1791 if (Width != NewWidth) {
1801 }
else if (!Ty->isFloatTy() && !Ty->isDoubleTy() && !Ty->isHalfTy())
1804 Value *Args[] = {SrcLHS, SrcRHS,
1805 ConstantInt::get(CC->
getType(), SrcPred)};
1807 NewIID, {
II.getType(), SrcLHS->
getType()}, Args);
1814 case Intrinsic::amdgcn_mbcnt_hi:
1819 case Intrinsic::amdgcn_mbcnt_lo: {
1832 if (std::optional<ConstantRange> ExistingRange =
II.getRange()) {
1833 ComputedRange = ComputedRange.
intersectWith(*ExistingRange);
1834 if (ComputedRange == *ExistingRange)
1838 II.addRangeRetAttr(ComputedRange);
1841 case Intrinsic::amdgcn_ballot: {
1842 Value *Arg =
II.getArgOperand(0);
1847 if (Src->isZero()) {
1852 if (ST->isWave32() &&
II.getType()->getIntegerBitWidth() == 64) {
1859 {IC.Builder.getInt32Ty()},
1860 {II.getArgOperand(0)}),
1867 case Intrinsic::amdgcn_wavefrontsize: {
1868 if (ST->isWaveSizeKnown())
1870 II, ConstantInt::get(
II.getType(), ST->getWavefrontSize()));
1873 case Intrinsic::amdgcn_wqm_vote: {
1880 case Intrinsic::amdgcn_kill: {
1882 if (!
C || !
C->getZExtValue())
1888 case Intrinsic::amdgcn_s_sendmsg:
1889 case Intrinsic::amdgcn_s_sendmsghalt: {
1895 Value *M0Val =
II.getArgOperand(1);
1901 decodeMsg(MsgImm->getZExtValue(), MsgId, OpId, StreamId, *ST);
1903 if (!msgDoesNotUseM0(MsgId, *ST))
1907 II.dropUBImplyingAttrsAndMetadata();
1911 case Intrinsic::amdgcn_update_dpp: {
1912 Value *Old =
II.getArgOperand(0);
1917 if (BC->isNullValue() || RM->getZExtValue() != 0xF ||
1924 case Intrinsic::amdgcn_permlane16:
1925 case Intrinsic::amdgcn_permlane16_var:
1926 case Intrinsic::amdgcn_permlanex16:
1927 case Intrinsic::amdgcn_permlanex16_var: {
1929 Value *VDstIn =
II.getArgOperand(0);
1934 unsigned int FiIdx = (IID == Intrinsic::amdgcn_permlane16 ||
1935 IID == Intrinsic::amdgcn_permlanex16)
1942 unsigned int BcIdx = FiIdx + 1;
1951 case Intrinsic::amdgcn_wave_shuffle:
1953 case Intrinsic::amdgcn_permlane64:
1954 case Intrinsic::amdgcn_readfirstlane:
1955 case Intrinsic::amdgcn_readlane:
1956 case Intrinsic::amdgcn_ds_bpermute: {
1958 unsigned SrcIdx = IID == Intrinsic::amdgcn_ds_bpermute ? 1 : 0;
1959 const Use &Src =
II.getArgOperandUse(SrcIdx);
1963 if (IID == Intrinsic::amdgcn_readlane &&
1970 if (IID == Intrinsic::amdgcn_ds_bpermute) {
1971 const Use &Lane =
II.getArgOperandUse(0);
1975 II.getModule(), Intrinsic::amdgcn_readlane,
II.getType());
1976 II.setCalledFunction(NewDecl);
1977 II.setOperand(0, Src);
1978 II.setOperand(1, NewLane);
1983 if (IID == Intrinsic::amdgcn_ds_bpermute)
1989 return std::nullopt;
1991 case Intrinsic::amdgcn_writelane: {
1995 return std::nullopt;
1997 case Intrinsic::amdgcn_trig_preop: {
2000 if (!
II.getType()->isDoubleTy())
2003 Value *Src =
II.getArgOperand(0);
2004 Value *Segment =
II.getArgOperand(1);
2013 if (StrippedSign != Src)
2016 if (
II.isStrictFP())
2038 unsigned Shift = SegmentVal * 53;
2043 static const uint32_t TwoByPi[] = {
2044 0xa2f9836e, 0x4e441529, 0xfc2757d1, 0xf534ddc0, 0xdb629599, 0x3c439041,
2045 0xfe5163ab, 0xdebbc561, 0xb7246e3a, 0x424dd2e0, 0x06492eea, 0x09d1921c,
2046 0xfe1deb1c, 0xb129a73e, 0xe88235f5, 0x2ebb4484, 0xe99c7026, 0xb45f7e41,
2047 0x3991d639, 0x835339f4, 0x9c845f8b, 0xbdf9283b, 0x1ff897ff, 0xde05980f,
2048 0xef2f118b, 0x5a0a6d1f, 0x6d367ecf, 0x27cb09b7, 0x4f463f66, 0x9e5fea2d,
2049 0x7527bac7, 0xebe5f17b, 0x3d0739f7, 0x8a5292ea, 0x6bfb5fb1, 0x1f8d5d08,
2053 unsigned Idx = Shift >> 5;
2054 if (Idx + 2 >= std::size(TwoByPi)) {
2059 unsigned BShift = Shift & 0x1f;
2063 Thi = (Thi << BShift) | (Tlo >> (64 - BShift));
2067 int Scale = -53 - Shift;
2074 case Intrinsic::amdgcn_fmul_legacy: {
2075 Value *Op0 =
II.getArgOperand(0);
2076 Value *Op1 =
II.getArgOperand(1);
2078 for (
Value *Src : {Op0, Op1}) {
2099 case Intrinsic::amdgcn_fma_legacy: {
2100 Value *Op0 =
II.getArgOperand(0);
2101 Value *Op1 =
II.getArgOperand(1);
2102 Value *Op2 =
II.getArgOperand(2);
2104 for (
Value *Src : {Op0, Op1, Op2}) {
2126 II.getModule(), Intrinsic::fma,
II.getType()));
2131 case Intrinsic::amdgcn_is_shared:
2132 case Intrinsic::amdgcn_is_private: {
2133 Value *Src =
II.getArgOperand(0);
2143 case Intrinsic::amdgcn_make_buffer_rsrc: {
2144 Value *Src =
II.getArgOperand(0);
2147 return std::nullopt;
2149 case Intrinsic::amdgcn_raw_buffer_store_format:
2150 case Intrinsic::amdgcn_struct_buffer_store_format:
2151 case Intrinsic::amdgcn_raw_tbuffer_store:
2152 case Intrinsic::amdgcn_struct_tbuffer_store:
2153 case Intrinsic::amdgcn_image_store_1d:
2154 case Intrinsic::amdgcn_image_store_1darray:
2155 case Intrinsic::amdgcn_image_store_2d:
2156 case Intrinsic::amdgcn_image_store_2darray:
2157 case Intrinsic::amdgcn_image_store_2darraymsaa:
2158 case Intrinsic::amdgcn_image_store_2dmsaa:
2159 case Intrinsic::amdgcn_image_store_3d:
2160 case Intrinsic::amdgcn_image_store_cube:
2161 case Intrinsic::amdgcn_image_store_mip_1d:
2162 case Intrinsic::amdgcn_image_store_mip_1darray:
2163 case Intrinsic::amdgcn_image_store_mip_2d:
2164 case Intrinsic::amdgcn_image_store_mip_2darray:
2165 case Intrinsic::amdgcn_image_store_mip_3d:
2166 case Intrinsic::amdgcn_image_store_mip_cube: {
2171 if (ST->hasDefaultComponentBroadcast())
2173 else if (ST->hasDefaultComponentZero())
2178 int DMaskIdx = getAMDGPUImageDMaskIntrinsic(
II.getIntrinsicID()) ? 1 : -1;
2186 case Intrinsic::amdgcn_prng_b32: {
2187 auto *Src =
II.getArgOperand(0);
2191 return std::nullopt;
2193 case Intrinsic::amdgcn_mfma_scale_f32_16x16x128_f8f6f4:
2194 case Intrinsic::amdgcn_mfma_scale_f32_32x32x64_f8f6f4: {
2195 Value *Src0 =
II.getArgOperand(0);
2196 Value *Src1 =
II.getArgOperand(1);
2202 auto getFormatNumRegs = [](
unsigned FormatVal) {
2203 switch (FormatVal) {
2217 bool MadeChange =
false;
2218 unsigned Src0NumElts = getFormatNumRegs(CBSZ);
2219 unsigned Src1NumElts = getFormatNumRegs(BLGP);
2223 if (Src0Ty->getNumElements() > Src0NumElts) {
2230 if (Src1Ty->getNumElements() > Src1NumElts) {
2238 return std::nullopt;
2249 case Intrinsic::amdgcn_wmma_f32_16x16x128_f8f6f4:
2250 case Intrinsic::amdgcn_wmma_scale_f32_16x16x128_f8f6f4:
2251 case Intrinsic::amdgcn_wmma_scale16_f32_16x16x128_f8f6f4: {
2252 Value *Src0 =
II.getArgOperand(1);
2253 Value *Src1 =
II.getArgOperand(3);
2259 bool MadeChange =
false;
2265 if (Src0Ty->getNumElements() > Src0NumElts) {
2272 if (Src1Ty->getNumElements() > Src1NumElts) {
2280 return std::nullopt;
2297 return std::nullopt;
2310 int DMaskIdx,
bool IsLoad) {
2313 :
II.getOperand(0)->getType());
2314 unsigned VWidth = IIVTy->getNumElements();
2317 Type *EltTy = IIVTy->getElementType();
2329 const unsigned UnusedComponentsAtFront = DemandedElts.
countr_zero();
2334 DemandedElts = (1 << ActiveBits) - 1;
2336 if (UnusedComponentsAtFront > 0) {
2337 static const unsigned InvalidOffsetIdx = 0xf;
2340 switch (
II.getIntrinsicID()) {
2341 case Intrinsic::amdgcn_raw_buffer_load:
2342 case Intrinsic::amdgcn_raw_ptr_buffer_load:
2345 case Intrinsic::amdgcn_s_buffer_load:
2349 if (ActiveBits == 4 && UnusedComponentsAtFront == 1)
2350 OffsetIdx = InvalidOffsetIdx;
2354 case Intrinsic::amdgcn_struct_buffer_load:
2355 case Intrinsic::amdgcn_struct_ptr_buffer_load:
2360 OffsetIdx = InvalidOffsetIdx;
2364 if (OffsetIdx != InvalidOffsetIdx) {
2366 DemandedElts &= ~((1 << UnusedComponentsAtFront) - 1);
2367 auto *
Offset = Args[OffsetIdx];
2368 unsigned SingleComponentSizeInBits =
2370 unsigned OffsetAdd =
2371 UnusedComponentsAtFront * SingleComponentSizeInBits / 8;
2372 auto *OffsetAddVal = ConstantInt::get(
Offset->getType(), OffsetAdd);
2389 unsigned NewDMaskVal = 0;
2390 unsigned OrigLdStIdx = 0;
2391 for (
unsigned SrcIdx = 0; SrcIdx < 4; ++SrcIdx) {
2392 const unsigned Bit = 1 << SrcIdx;
2393 if (!!(DMaskVal & Bit)) {
2394 if (!!DemandedElts[OrigLdStIdx])
2400 if (DMaskVal != NewDMaskVal)
2401 Args[DMaskIdx] = ConstantInt::get(DMask->
getType(), NewDMaskVal);
2404 unsigned NewNumElts = DemandedElts.
popcount();
2408 if (NewNumElts >= VWidth && DemandedElts.
isMask()) {
2410 II.setArgOperand(DMaskIdx, Args[DMaskIdx]);
2422 OverloadTys[0] = NewTy;
2426 for (
unsigned OrigStoreIdx = 0; OrigStoreIdx < VWidth; ++OrigStoreIdx)
2427 if (DemandedElts[OrigStoreIdx])
2430 if (NewNumElts == 1)
2437 II.getIntrinsicID(), OverloadTys, Args);
2440 AttributeList OldAttrList =
II.getAttributes();
2444 if (NewNumElts == 1) {
2450 unsigned NewLoadIdx = 0;
2451 for (
unsigned OrigLoadIdx = 0; OrigLoadIdx < VWidth; ++OrigLoadIdx) {
2452 if (!!DemandedElts[OrigLoadIdx])
2468 APInt &UndefElts)
const {
2473 const unsigned FirstElt = DemandedElts.
countr_zero();
2475 const unsigned MaskLen = LastElt - FirstElt + 1;
2477 unsigned OldNumElts = VT->getNumElements();
2478 if (MaskLen == OldNumElts && MaskLen != 1)
2481 Type *EltTy = VT->getElementType();
2489 Value *Src =
II.getArgOperand(0);
2494 II.getOperandBundlesAsDefs(OpBundles);
2511 for (
unsigned I = 0;
I != MaskLen; ++
I) {
2512 if (DemandedElts[FirstElt +
I])
2513 ExtractMask[
I] = FirstElt +
I;
2522 for (
unsigned I = 0;
I != MaskLen; ++
I) {
2523 if (DemandedElts[FirstElt +
I])
2524 InsertMask[FirstElt +
I] =
I;
2536 SimplifyAndSetOp)
const {
2537 switch (
II.getIntrinsicID()) {
2538 case Intrinsic::amdgcn_readfirstlane:
2539 SimplifyAndSetOp(&
II, 0, DemandedElts, UndefElts);
2541 case Intrinsic::amdgcn_raw_buffer_load:
2542 case Intrinsic::amdgcn_raw_ptr_buffer_load:
2543 case Intrinsic::amdgcn_raw_buffer_load_format:
2544 case Intrinsic::amdgcn_raw_ptr_buffer_load_format:
2545 case Intrinsic::amdgcn_raw_tbuffer_load:
2546 case Intrinsic::amdgcn_raw_ptr_tbuffer_load:
2547 case Intrinsic::amdgcn_s_buffer_load:
2548 case Intrinsic::amdgcn_struct_buffer_load:
2549 case Intrinsic::amdgcn_struct_ptr_buffer_load:
2550 case Intrinsic::amdgcn_struct_buffer_load_format:
2551 case Intrinsic::amdgcn_struct_ptr_buffer_load_format:
2552 case Intrinsic::amdgcn_struct_tbuffer_load:
2553 case Intrinsic::amdgcn_struct_ptr_tbuffer_load:
2556 if (getAMDGPUImageDMaskIntrinsic(
II.getIntrinsicID())) {
2562 return std::nullopt;
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static Value * createPermlane16(IRBuilderBase &B, Value *Val, uint32_t Lo, uint32_t Hi)
Emit v_permlane16 with the precomputed lane-select halves.
static std::optional< unsigned > matchRowSharePattern(ArrayRef< uint8_t > Ids)
Match a row-share pattern: all 16 lanes of each row read the same source lane.
static bool matchMirrorPattern(ArrayRef< uint8_t > Ids)
Match an N-lane reversal (mirror) pattern.
static bool canSafelyConvertTo16Bit(Value &V, bool IsFloat, bool AllowI16SExt=false)
static bool tryBuildShuffleMap(Value *Index, const GCNSubtarget &ST, SmallVectorImpl< uint8_t > &Ids, const DataLayout &DL)
Build the per-lane shuffle map by evaluating Index for every lane in the wave.
static std::optional< unsigned > matchQuadPermPattern(ArrayRef< uint8_t > Ids)
Match a 4-lane (quad) permutation, encoded as the v_mov_b32_dpp QUAD_PERM control word: bits[1:0]=Ids...
static std::optional< unsigned > matchDsSwizzleRotatePattern(ArrayRef< uint8_t > Ids)
Match a GFX9+ DS_SWIZZLE rotate-mode permutation: a cyclic left-rotation of all 32 lanes within each ...
static std::optional< unsigned > matchHalfRowPermPattern(ArrayRef< uint8_t > Ids)
Match an 8-lane arbitrary permutation, encoded as the v_mov_b32_dpp8 24-bit selector (three bits per ...
static std::optional< unsigned > matchRowXMaskPattern(ArrayRef< uint8_t > Ids)
Match an XOR mask pattern within each 16-lane row: Ids[J] == Mask ^ J, with Mask in [1,...
static constexpr auto matchHalfRowMirrorPattern
static Value * createPermlaneX16(IRBuilderBase &B, Value *Val, uint32_t Lo, uint32_t Hi)
Emit v_permlanex16 with the precomputed lane-select halves.
static bool isRowPattern(ArrayRef< uint8_t > Ids)
Match an N-lane row pattern: each lane in [0, N) reads from a source lane in the same N-lane row,...
static bool canContractSqrtToRsq(const FPMathOperator *SqrtOp)
Return true if it's legal to contract llvm.amdgcn.rcp(llvm.sqrt)
static bool isTriviallyUniform(const Use &U)
Return true if we can easily prove that use U is uniform.
static CallInst * rewriteCall(IRBuilderBase &B, CallInst &Old, Function &NewCallee, ArrayRef< Value * > Ops)
static Value * convertTo16Bit(Value &V, InstCombiner::BuilderTy &Builder)
static constexpr auto isFullRowPattern
static constexpr auto isQuadPattern
static APInt trimTrailingZerosInVector(InstCombiner &IC, Value *UseV, Instruction *I)
static uint64_t computePermlane16Masks(ArrayRef< uint8_t > Ids)
Pack a 16-lane permutation into a single 64-bit value: four bits per output lane, lane J in bits [J*4...
static bool matchHalfWaveSwapPattern(ArrayRef< uint8_t > Ids)
Match a half-wave swap: lane J reads from lane J ^ 32.
static bool hasPeriodicLayout(ArrayRef< uint8_t > Ids)
Lanes are partitioned into groups of Period; each group is a translated copy of the first: Ids[I] = I...
static std::optional< Instruction * > tryOptimizeShufflePattern(InstCombiner &IC, IntrinsicInst &II, const GCNSubtarget &ST)
Try to fold a wave_shuffle/ds_bpermute whose lane index is a constant function of the lane ID into a ...
static constexpr auto isHalfRowPattern
static APInt defaultComponentBroadcast(Value *V)
static std::optional< unsigned > matchDsSwizzleBitmaskPattern(ArrayRef< uint8_t > Ids)
Match a DS_SWIZZLE bitmask-mode permutation: dst_lane = ((src_lane & AND) | OR) ^ XOR with each mask ...
static Value * createDsSwizzle(IRBuilderBase &B, Value *Val, unsigned Offset, const DataLayout &DL)
Emit ds_swizzle with the given immediate, bitcasting/converting between pointer/float types and i32 a...
static std::optional< Instruction * > modifyIntrinsicCall(IntrinsicInst &OldIntr, Instruction &InstToReplace, unsigned NewIntr, InstCombiner &IC, std::function< void(SmallVectorImpl< Value * > &, SmallVectorImpl< Type * > &)> Func)
Applies Func(OldIntr.Args, OldIntr.ArgTys), creates intrinsic call with modified arguments (based on ...
static Value * matchShuffleToHWIntrinsic(IRBuilderBase &B, Value *Src, ArrayRef< uint8_t > Ids, const GCNSubtarget &ST, const DataLayout &DL)
Given a shuffle map, try to emit the best hardware intrinsic.
static std::optional< unsigned > matchRowRotatePattern(ArrayRef< uint8_t > Ids)
Match a 16-lane cyclic rotation; returns the rotation amount in [1, 15].
static bool isCrossRowPattern(ArrayRef< uint8_t > Ids)
Match a cross-row permutation suitable for v_permlanex16: every lane in the low 16-lane half reads fr...
static bool isThreadID(const GCNSubtarget &ST, Value *V)
static Value * createUpdateDpp(IRBuilderBase &B, Value *Val, unsigned Ctrl)
Emit v_mov_b32_dpp with the given control word, row/bank masks 0xF, and bound_ctrl=1 so out-of-bounds...
static APFloat fmed3AMDGCN(const APFloat &Src0, const APFloat &Src1, const APFloat &Src2)
static Value * simplifyAMDGCNMemoryIntrinsicDemanded(InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, int DMaskIdx=-1, bool IsLoad=true)
Implement SimplifyDemandedVectorElts for amdgcn buffer and image intrinsics.
static std::optional< Instruction * > simplifyAMDGCNImageIntrinsic(const GCNSubtarget *ST, const AMDGPU::ImageDimIntrinsicInfo *ImageDimIntr, IntrinsicInst &II, InstCombiner &IC)
static Value * createMovDpp8(IRBuilderBase &B, Value *Val, unsigned Selector)
Emit v_mov_b32_dpp8 with the given 24-bit lane selector.
static Value * matchFPExtFromF16(Value *Arg)
Match an fpext from half to float, or a constant we can convert.
static constexpr auto matchFullRowMirrorPattern
static std::optional< unsigned > evalLaneExpr(Value *V, unsigned Lane, const GCNSubtarget &ST, const DataLayout &DL, unsigned Depth=0)
Evaluate V as a function of the lane ID and return its value on Lane, or std::nullopt if V is not a c...
static Value * createPermlane64(IRBuilderBase &B, Value *Val)
Emit v_permlane64 (swap of the two 32-lane halves of a wave64).
Contains the definition of a TargetInstrInfo class that is common to all AMD GPUs.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Utilities for dealing with flags related to floating point properties and mode controls.
AMD GCN specific subclass of TargetSubtarget.
This file provides the interface for the instcombine pass implementation.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
MachineInstr unsigned OpIdx
uint64_t IntrinsicInst * II
Provides some synthesis utilities to produce sequences of values.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static constexpr roundingMode rmTowardZero
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & IEEEhalf()
static APFloat getQNaN(const fltSemantics &Sem, bool Negative=false, const APInt *payload=nullptr)
Factory for QNaN values.
opStatus divide(const APFloat &RHS, roundingMode RM)
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
bool bitwiseIsEqual(const APFloat &RHS) const
bool isPosInfinity() const
const fltSemantics & getSemantics() const
APFloat makeQuiet() const
Assuming this is an IEEE-754 NaN value, quiet its signaling bit.
APInt bitcastToAPInt() const
bool isNegInfinity() const
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
uint64_t getZExtValue() const
Get zero extended value.
unsigned popcount() const
Count the number of bits set.
LLVM_ABI uint64_t extractBitsAsZExtValue(unsigned numBits, unsigned bitPosition) const
unsigned getActiveBits() const
Compute the number of active bits in the value.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
unsigned countr_zero() const
Count the number of trailing zero bits.
bool isMask(unsigned numBits) const
Represent a constant reference to an array (0 or more elements consecutively in memory),...
ArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
size_t size() const
Get the array size.
static LLVM_ABI Attribute getWithDereferenceableBytes(LLVMContext &Context, uint64_t Bytes)
LLVM_ABI const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr if the function does no...
bool isTypeLegal(Type *Ty) const override
LLVM_ABI void getOperandBundlesAsDefs(SmallVectorImpl< OperandBundleDef > &Defs) const
Return the list of operand bundles attached to this instruction as a vector of OperandBundleDefs.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
void setAttributes(AttributeList A)
Set the attributes for this call.
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
AttributeList getAttributes() const
Return the attributes for this call.
This class represents a function call, abstracting a target machine's calling convention.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
bool isFPPredicate() const
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
ConstantFP - Floating Point Values [float, double].
const APFloat & getValueAPF() const
static LLVM_ABI ConstantFP * getZero(Type *Ty, bool Negative=false)
static LLVM_ABI ConstantFP * getNaN(Type *Ty, bool Negative=false, uint64_t Payload=0)
static LLVM_ABI ConstantFP * getInfinity(Type *Ty, bool Negative=false)
This is the shared class of boolean and integer constants.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
const APInt & getValue() const
Return the constant as an APInt value reference.
This class represents a range of values.
LLVM_ABI ConstantRange add(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an addition of a value in this ran...
LLVM_ABI bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
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.
This is an important base class in LLVM.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Tagged union holding either a T or a Error.
This class represents an extension of floating point types.
Utility class for floating point operations which can have information about relaxed accuracy require...
FastMathFlags getFastMathFlags() const
Convenience function for getting all the fast-math flags.
bool hasApproxFunc() const
Test if this operation allows approximations of math library functions or intrinsics.
LLVM_ABI float getFPAccuracy() const
Get the maximum error permitted by this operation in ULPs.
Convenience struct for specifying and reasoning about fast-math flags.
bool allowContract() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
bool simplifyDemandedLaneMaskArg(InstCombiner &IC, IntrinsicInst &II, unsigned LaneAgIdx) const
Simplify a lane index operand (e.g.
std::optional< Instruction * > instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const override
Instruction * hoistLaneIntrinsicThroughOperand(InstCombiner &IC, IntrinsicInst &II) const
std::optional< Value * > simplifyDemandedVectorEltsIntrinsic(InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts, APInt &UndefElts2, APInt &UndefElts3, std::function< void(Instruction *, unsigned, APInt, APInt &)> SimplifyAndSetOp) const override
KnownIEEEMode fpenvIEEEMode(const Instruction &I) const
Return KnownIEEEMode::On if we know if the use context can assume "amdgpu-ieee"="true" and KnownIEEEM...
Value * simplifyAMDGCNLaneIntrinsicDemanded(InstCombiner &IC, IntrinsicInst &II, const APInt &DemandedElts, APInt &UndefElts) const
bool canSimplifyLegacyMulToMul(const Instruction &I, const Value *Op0, const Value *Op1, InstCombiner &IC) const
Common base class shared among various IRBuilders.
LLVM_ABI CallInst * CreateIntrinsicWithoutFolding(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={})
Create a call to intrinsic ID with Args, mangled using OverloadTypes.
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
ConstantInt * getTrue()
Get the constant value for i1 true.
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateExtractVector(Type *DstType, Value *SrcVec, Value *Idx, const Twine &Name="")
Create a call to the vector.extract intrinsic.
BasicBlock * GetInsertBlock() const
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Value * CreateMaxNum(Value *LHS, Value *RHS, FMFSource FMFSource={}, const Twine &Name="")
Create call to the maxnum intrinsic.
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, 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.
Value * CreateMaximumNum(Value *LHS, Value *RHS, const Twine &Name="")
Create call to the maximum intrinsic.
Value * CreateMinNum(Value *LHS, Value *RHS, FMFSource FMFSource={}, const Twine &Name="")
Create call to the minnum intrinsic.
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateFAddFMF(Value *L, Value *R, FMFSource FMFSource, const Twine &Name="", MDNode *FPMD=nullptr)
Value * CreateMinimumNum(Value *LHS, Value *RHS, const Twine &Name="")
Create call to the minimumnum intrinsic.
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateFMulFMF(Value *L, Value *R, FMFSource FMFSource, const Twine &Name="", MDNode *FPMD=nullptr)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
The core instruction combiner logic.
const DataLayout & getDataLayout() const
virtual Instruction * eraseInstFromFunction(Instruction &I)=0
Combiner aware instruction erasure.
DominatorTree & getDominatorTree() const
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
virtual bool SimplifyDemandedBits(Instruction *I, unsigned OpNo, const APInt &DemandedMask, KnownBits &Known, const SimplifyQuery &Q, unsigned Depth=0)=0
IRBuilder< TargetFolder, IRBuilderInstCombineInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
static Value * stripSignOnlyFPOps(Value *Val)
Ignore all operations which only change the sign of a value, returning the underlying magnitude value...
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
const SimplifyQuery & getSimplifyQuery() const
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI void copyFastMathFlags(FastMathFlags FMF)
Convenience function for transferring all fast-math flag values to this instruction,...
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
Class to represent integer types.
A wrapper class for inspecting calls to intrinsic functions.
A Module instance is used to store all the information related to an LLVM module.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isPointerTy() const
True if this is an instance of PointerType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
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.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
static LLVM_ABI Type * getHalfTy(LLVMContext &C)
bool isVoidTy() const
Return true if this is 'void'.
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
const Use & getOperandUse(unsigned i) const
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI bool hasOneUser() const
Return true if there is exactly one user of this value.
LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
const ParentTy * getParent() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_READONLY const MIMGOffsetMappingInfo * getMIMGOffsetMappingInfo(unsigned Offset)
uint8_t wmmaScaleF8F6F4FormatToNumRegs(unsigned Fmt)
const ImageDimIntrinsicInfo * getImageDimIntrinsicByBaseOpcode(unsigned BaseOpcode, unsigned Dim)
LLVM_READONLY const MIMGMIPMappingInfo * getMIMGMIPMappingInfo(unsigned MIP)
bool isArgPassedInSGPR(const Argument *A)
bool isIntrinsicAlwaysUniform(unsigned IntrID)
LLVM_READONLY const MIMGBiasMappingInfo * getMIMGBiasMappingInfo(unsigned Bias)
LLVM_READONLY const MIMGLZMappingInfo * getMIMGLZMappingInfo(unsigned L)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
const ImageDimIntrinsicInfo * getImageDimIntrinsicInfo(unsigned Intr)
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
LLVM_ABI bool isSignatureValid(Intrinsic::ID ID, FunctionType *FT, SmallVectorImpl< Type * > &OverloadTys, raw_ostream &OS=nulls())
Returns true if FT is a valid function type for intrinsic ID.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
auto m_Cmp()
Matches any compare instruction and ignore it.
bool match(Val *V, const Pattern &P)
match_bind< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
ap_match< APFloat > m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)
Matches ExtractElementInst.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
auto m_Value()
Match an arbitrary value and ignore it.
CastInst_match< OpTy, FPExtInst > m_FPExt(const OpTy &Op)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
cstfp_pred_ty< is_finitenonzero > m_FiniteNonZero()
Match a finite non-zero FP constant.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > > m_ZExtOrSExt(const OpTy &Op)
auto m_ConstantFP()
Match an arbitrary ConstantFP and ignore it.
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
@ Known
Known to have no common set bits.
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.
LLVM_ABI Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Instruction *I=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
APFloat frexp(const APFloat &X, int &Exp, APFloat::roundingMode RM)
Equivalent of C standard library function.
auto dyn_cast_or_null(const Y &Val)
LLVM_READONLY APFloat maxnum(const APFloat &A, const APFloat &B)
Implements IEEE-754 2008 maxNum semantics.
constexpr unsigned MaxAnalysisRecursionDepth
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode RM)
Returns: X * 2^Exp for integral exponents.
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
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
LLVM_ABI Value * findScalarElement(Value *V, unsigned EltNo)
Given a vector and an element number, see if the scalar value is already around as a register,...
@ NearestTiesToEven
roundTiesToEven.
LLVM_ABI bool isKnownNeverInfOrNaN(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point value can never contain a NaN or infinity.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
LLVM_ABI Constant * ConstantFoldInstOperands(const Instruction *I, ArrayRef< Constant * > Ops, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, bool AllowNonDeterministic=true)
ConstantFoldInstOperands - Attempt to constant fold an instruction with the specified operands.
constexpr uint64_t Make_64(uint32_t High, uint32_t Low)
Make a 64-bit integer from a high / low pair of 32-bit integers.
LLVM_ABI ConstantRange computeConstantRange(const Value *V, bool ForSigned, const SimplifyQuery &SQ, unsigned Depth=0)
Determine the possible constant range of an integer or vector of integer value.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
SimplifyQuery getWithInstruction(const Instruction *I) const
LLVM_ABI bool isUndefValue(Value *V) const
If CanUseUndef is true, returns whether V is undef.