21#include "llvm/IR/IntrinsicsAMDGPU.h"
28#define DEBUG_TYPE "AMDGPUtti"
32struct AMDGPUImageDMaskIntrinsic {
36#define GET_AMDGPUImageDMaskIntrinsicTable_IMPL
37#include "InstCombineTables.inc"
50 assert(Cmp0 != APFloat::cmpUnordered &&
"nans handled separately");
51 if (Cmp0 == APFloat::cmpEqual)
55 assert(Cmp1 != APFloat::cmpUnordered &&
"nans handled separately");
56 if (Cmp1 == APFloat::cmpEqual)
67 Type *VTy = V.getType();
73 if (
ConstantFP *ConstFloat = dyn_cast<ConstantFP>(&V)) {
76 APFloat FloatValue(ConstFloat->getValueAPF());
77 bool LosesInfo =
true;
78 FloatValue.
convert(APFloat::IEEEhalf(), APFloat::rmTowardZero,
83 if (
ConstantInt *ConstInt = dyn_cast<ConstantInt>(&V)) {
86 APInt IntValue(ConstInt->getValue());
105 Type *VTy = V.getType();
106 if (isa<FPExtInst>(&V) || isa<SExtInst>(&V) || isa<ZExtInst>(&V))
107 return cast<Instruction>(&V)->getOperand(0);
138 if (isa<FPMathOperator>(NewCall))
145 bool RemoveOldIntr = &OldIntr != &InstToReplace;
154static std::optional<Instruction *>
159 if (
const auto *LZMappingInfo =
161 if (
auto *ConstantLod =
163 if (ConstantLod->isZero() || ConstantLod->isNegative()) {
168 II, II, NewImageDimIntr->
Intr, IC, [&](
auto &Args,
auto &ArgTys) {
169 Args.erase(Args.begin() + ImageDimIntr->LodIndex);
176 if (
const auto *MIPMappingInfo =
178 if (
auto *ConstantMip =
180 if (ConstantMip->isZero()) {
185 II, II, NewImageDimIntr->
Intr, IC, [&](
auto &Args,
auto &ArgTys) {
186 Args.erase(Args.begin() + ImageDimIntr->MipIndex);
193 if (
const auto *BiasMappingInfo =
195 if (
auto *ConstantBias =
197 if (ConstantBias->isZero()) {
202 II, II, NewImageDimIntr->
Intr, IC, [&](
auto &Args,
auto &ArgTys) {
203 Args.erase(Args.begin() + ImageDimIntr->BiasIndex);
204 ArgTys.erase(ArgTys.begin() + ImageDimIntr->BiasTyArg);
211 if (
const auto *OffsetMappingInfo =
213 if (
auto *ConstantOffset =
215 if (ConstantOffset->isZero()) {
218 OffsetMappingInfo->NoOffset, ImageDimIntr->
Dim);
220 II, II, NewImageDimIntr->
Intr, IC, [&](
auto &Args,
auto &ArgTys) {
221 Args.erase(Args.begin() + ImageDimIntr->OffsetIndex);
228 if (ST->hasD16Images()) {
241 if (
User->getOpcode() == Instruction::FPTrunc &&
245 [&](
auto &Args,
auto &ArgTys) {
248 ArgTys[0] = User->getType();
256 if (!ST->hasA16() && !ST->hasG16())
263 bool FloatCoord =
false;
265 bool OnlyDerivatives =
false;
268 OperandIndex < ImageDimIntr->VAddrEnd; OperandIndex++) {
272 if (OperandIndex < ImageDimIntr->CoordStart ||
277 OnlyDerivatives =
true;
286 if (!OnlyDerivatives && !ST->hasA16())
287 OnlyDerivatives =
true;
290 if (!OnlyDerivatives && ImageDimIntr->
NumBiasArgs != 0) {
293 "Only image instructions with a sampler can have a bias");
295 OnlyDerivatives =
true;
298 if (OnlyDerivatives && (!ST->hasG16() || ImageDimIntr->
GradientStart ==
307 ArgTys[ImageDimIntr->GradientTyArg] = CoordType;
308 if (!OnlyDerivatives) {
309 ArgTys[ImageDimIntr->CoordTyArg] = CoordType;
312 if (ImageDimIntr->NumBiasArgs != 0)
313 ArgTys[ImageDimIntr->BiasTyArg] = Type::getHalfTy(II.getContext());
319 OperandIndex < EndIndex; OperandIndex++) {
321 convertTo16Bit(*II.getOperand(OperandIndex), IC.Builder);
326 Value *Bias = II.getOperand(ImageDimIntr->BiasIndex);
327 Args[ImageDimIntr->BiasIndex] = convertTo16Bit(*Bias, IC.Builder);
379 auto *VTy = cast<FixedVectorType>(UseV->
getType());
380 unsigned VWidth = VTy->getNumElements();
383 for (
int i = VWidth - 1; i > 0; --i) {
388 if (
auto *ConstElt = dyn_cast<Constant>(Elt)) {
389 if (!ConstElt->isNullValue() && !isa<UndefValue>(Elt))
404 auto *VTy = cast<FixedVectorType>(V->getType());
405 unsigned VWidth = VTy->getNumElements();
410 if (
auto *SVI = dyn_cast<ShuffleVectorInst>(V))
411 SVI->getShuffleMask(ShuffleMask);
413 for (
int I = VWidth - 1;
I > 0; --
I) {
414 if (ShuffleMask.
empty()) {
416 if (!Elt || (Elt != FirstComponent && !isa<UndefValue>(Elt)))
443std::optional<Instruction *>
447 case Intrinsic::amdgcn_rcp: {
451 if (isa<UndefValue>(Src)) {
460 if (
const ConstantFP *
C = dyn_cast<ConstantFP>(Src)) {
461 const APFloat &ArgVal =
C->getValueAPF();
472 FastMathFlags FMF = cast<FPMathOperator>(II).getFastMathFlags();
475 auto *SrcCI = dyn_cast<IntrinsicInst>(Src);
479 auto IID = SrcCI->getIntrinsicID();
484 if (IID == Intrinsic::amdgcn_sqrt || IID == Intrinsic::sqrt) {
494 SrcCI->getModule(), Intrinsic::amdgcn_rsq, {SrcCI->getType()});
505 case Intrinsic::amdgcn_sqrt:
506 case Intrinsic::amdgcn_rsq: {
510 if (isa<UndefValue>(Src)) {
517 if (IID == Intrinsic::amdgcn_sqrt && Src->getType()->isHalfTy()) {
519 II.
getModule(), Intrinsic::sqrt, {II.getType()});
526 case Intrinsic::amdgcn_log:
527 case Intrinsic::amdgcn_exp2: {
528 const bool IsLog = IID == Intrinsic::amdgcn_log;
529 const bool IsExp = IID == Intrinsic::amdgcn_exp2;
533 if (isa<PoisonValue>(Src))
540 if (
C->isInfinity()) {
543 if (!
C->isNegative())
547 if (IsExp &&
C->isNegative())
555 Constant *Quieted = ConstantFP::get(Ty,
C->getValue().makeQuiet());
560 if (
C->isZero() || (
C->getValue().isDenormal() && Ty->
isFloatTy())) {
562 : ConstantFP::get(Ty, 1.0);
566 if (IsLog &&
C->isNegative())
574 case Intrinsic::amdgcn_frexp_mant:
575 case Intrinsic::amdgcn_frexp_exp: {
577 if (
const ConstantFP *
C = dyn_cast<ConstantFP>(Src)) {
582 if (IID == Intrinsic::amdgcn_frexp_mant) {
584 II, ConstantFP::get(II.
getContext(), Significand));
594 if (isa<UndefValue>(Src)) {
600 case Intrinsic::amdgcn_class: {
603 const ConstantInt *CMask = dyn_cast<ConstantInt>(Src1);
615 if (isa<PoisonValue>(Src0) || isa<PoisonValue>(Src1))
630 case Intrinsic::amdgcn_cvt_pkrtz: {
633 if (
const ConstantFP *C0 = dyn_cast<ConstantFP>(Src0)) {
634 if (
const ConstantFP *C1 = dyn_cast<ConstantFP>(Src1)) {
638 APFloat Val0 = C0->getValueAPF();
639 APFloat Val1 = C1->getValueAPF();
650 if (isa<UndefValue>(Src0) && isa<UndefValue>(Src1)) {
656 case Intrinsic::amdgcn_cvt_pknorm_i16:
657 case Intrinsic::amdgcn_cvt_pknorm_u16:
658 case Intrinsic::amdgcn_cvt_pk_i16:
659 case Intrinsic::amdgcn_cvt_pk_u16: {
663 if (isa<UndefValue>(Src0) && isa<UndefValue>(Src1)) {
669 case Intrinsic::amdgcn_ubfe:
670 case Intrinsic::amdgcn_sbfe: {
673 if (isa<UndefValue>(Src)) {
684 if ((Width & (IntSize - 1)) == 0) {
689 if (Width >= IntSize) {
691 II, 2, ConstantInt::get(CWidth->
getType(), Width & (IntSize - 1)));
702 ConstantInt::get(COffset->
getType(),
Offset & (IntSize - 1)));
706 bool Signed = IID == Intrinsic::amdgcn_sbfe;
708 if (!CWidth || !COffset)
718 if (
Offset + Width < IntSize) {
722 RightShift->takeName(&II);
729 RightShift->takeName(&II);
732 case Intrinsic::amdgcn_exp:
733 case Intrinsic::amdgcn_exp_row:
734 case Intrinsic::amdgcn_exp_compr: {
740 bool IsCompr = IID == Intrinsic::amdgcn_exp_compr;
741 bool Changed =
false;
742 for (
int I = 0;
I < (IsCompr ? 2 : 4); ++
I) {
743 if ((!IsCompr && (EnBits & (1 <<
I)) == 0) ||
744 (IsCompr && ((EnBits & (0x3 << (2 *
I))) == 0))) {
746 if (!isa<UndefValue>(Src)) {
759 case Intrinsic::amdgcn_fmed3: {
780 if (
auto *CI = dyn_cast<CallInst>(V)) {
781 CI->copyFastMathFlags(&II);
791 if (isa<Constant>(Src0) && !isa<Constant>(Src1)) {
796 if (isa<Constant>(Src1) && !isa<Constant>(Src2)) {
801 if (isa<Constant>(Src0) && !isa<Constant>(Src1)) {
813 if (
const ConstantFP *C0 = dyn_cast<ConstantFP>(Src0)) {
814 if (
const ConstantFP *C1 = dyn_cast<ConstantFP>(Src1)) {
815 if (
const ConstantFP *C2 = dyn_cast<ConstantFP>(Src2)) {
840 case Intrinsic::amdgcn_icmp:
841 case Intrinsic::amdgcn_fcmp: {
844 int64_t CCVal =
CC->getZExtValue();
845 bool IsInteger = IID == Intrinsic::amdgcn_icmp;
855 if (
auto *CSrc0 = dyn_cast<Constant>(Src0)) {
856 if (
auto *CSrc1 = dyn_cast<Constant>(Src1)) {
874 NewCall->
addFnAttr(Attribute::Convergent);
885 2, ConstantInt::get(
CC->getType(),
static_cast<int>(SwapPred)));
932 ? Intrinsic::amdgcn_fcmp
933 : Intrinsic::amdgcn_icmp;
936 if (
auto *CmpType = dyn_cast<IntegerType>(Ty)) {
938 unsigned Width = CmpType->getBitWidth();
939 unsigned NewWidth = Width;
947 else if (Width <= 32)
949 else if (Width <= 64)
954 if (Width != NewWidth) {
968 II.
getModule(), NewIID, {II.getType(), SrcLHS->getType()});
969 Value *Args[] = {SrcLHS, SrcRHS,
970 ConstantInt::get(
CC->getType(), SrcPred)};
978 case Intrinsic::amdgcn_mbcnt_hi: {
984 case Intrinsic::amdgcn_ballot: {
985 if (
auto *Src = dyn_cast<ConstantInt>(II.
getArgOperand(0))) {
998 {IC.Builder.getInt32Ty()},
999 {II.getArgOperand(0)}),
1001 Call->takeName(&II);
1006 case Intrinsic::amdgcn_wqm_vote: {
1013 case Intrinsic::amdgcn_kill: {
1015 if (!
C || !
C->getZExtValue())
1021 case Intrinsic::amdgcn_update_dpp: {
1027 if (BC->isZeroValue() || RM->getZExtValue() != 0xF ||
1028 BM->getZExtValue() != 0xF || isa<UndefValue>(Old))
1034 case Intrinsic::amdgcn_permlane16:
1035 case Intrinsic::amdgcn_permlane16_var:
1036 case Intrinsic::amdgcn_permlanex16:
1037 case Intrinsic::amdgcn_permlanex16_var: {
1040 if (isa<UndefValue>(VDstIn))
1044 unsigned int FiIdx = (IID == Intrinsic::amdgcn_permlane16 ||
1045 IID == Intrinsic::amdgcn_permlanex16)
1052 unsigned int BcIdx = FiIdx + 1;
1061 case Intrinsic::amdgcn_permlane64:
1067 case Intrinsic::amdgcn_readfirstlane:
1068 case Intrinsic::amdgcn_readlane: {
1077 Instruction *SrcInst = dyn_cast<Instruction>(Src);
1084 PatternMatch::m_Intrinsic<Intrinsic::amdgcn_readfirstlane>())) {
1088 if (IID == Intrinsic::amdgcn_readfirstlane) {
1090 if (
match(Src, PatternMatch::m_Intrinsic<Intrinsic::amdgcn_readlane>())) {
1095 if (
match(Src, PatternMatch::m_Intrinsic<Intrinsic::amdgcn_readlane>(
1104 case Intrinsic::amdgcn_fmul_legacy: {
1119 FMul->takeName(&II);
1124 case Intrinsic::amdgcn_fma_legacy: {
1138 FAdd->takeName(&II);
1151 case Intrinsic::amdgcn_is_shared:
1152 case Intrinsic::amdgcn_is_private: {
1160 case Intrinsic::amdgcn_buffer_store_format:
1161 case Intrinsic::amdgcn_raw_buffer_store_format:
1162 case Intrinsic::amdgcn_struct_buffer_store_format:
1163 case Intrinsic::amdgcn_raw_tbuffer_store:
1164 case Intrinsic::amdgcn_struct_tbuffer_store:
1165 case Intrinsic::amdgcn_tbuffer_store:
1166 case Intrinsic::amdgcn_image_store_1d:
1167 case Intrinsic::amdgcn_image_store_1darray:
1168 case Intrinsic::amdgcn_image_store_2d:
1169 case Intrinsic::amdgcn_image_store_2darray:
1170 case Intrinsic::amdgcn_image_store_2darraymsaa:
1171 case Intrinsic::amdgcn_image_store_2dmsaa:
1172 case Intrinsic::amdgcn_image_store_3d:
1173 case Intrinsic::amdgcn_image_store_cube:
1174 case Intrinsic::amdgcn_image_store_mip_1d:
1175 case Intrinsic::amdgcn_image_store_mip_1darray:
1176 case Intrinsic::amdgcn_image_store_mip_2d:
1177 case Intrinsic::amdgcn_image_store_mip_2darray:
1178 case Intrinsic::amdgcn_image_store_mip_3d:
1179 case Intrinsic::amdgcn_image_store_mip_cube: {
1191 int DMaskIdx = getAMDGPUImageDMaskIntrinsic(II.
getIntrinsicID()) ? 1 : -1;
1204 return std::nullopt;
1217 int DMaskIdx,
bool IsLoad) {
1219 auto *IIVTy = cast<FixedVectorType>(IsLoad ? II.
getType()
1221 unsigned VWidth = IIVTy->getNumElements();
1224 Type *EltTy = IIVTy->getElementType();
1236 const unsigned UnusedComponentsAtFront = DemandedElts.
countr_zero();
1241 DemandedElts = (1 << ActiveBits) - 1;
1243 if (UnusedComponentsAtFront > 0) {
1244 static const unsigned InvalidOffsetIdx = 0xf;
1248 case Intrinsic::amdgcn_raw_buffer_load:
1249 case Intrinsic::amdgcn_raw_ptr_buffer_load:
1252 case Intrinsic::amdgcn_s_buffer_load:
1256 if (ActiveBits == 4 && UnusedComponentsAtFront == 1)
1257 OffsetIdx = InvalidOffsetIdx;
1261 case Intrinsic::amdgcn_struct_buffer_load:
1262 case Intrinsic::amdgcn_struct_ptr_buffer_load:
1267 OffsetIdx = InvalidOffsetIdx;
1271 if (OffsetIdx != InvalidOffsetIdx) {
1273 DemandedElts &= ~((1 << UnusedComponentsAtFront) - 1);
1274 auto *
Offset = Args[OffsetIdx];
1275 unsigned SingleComponentSizeInBits =
1277 unsigned OffsetAdd =
1278 UnusedComponentsAtFront * SingleComponentSizeInBits / 8;
1279 auto *OffsetAddVal = ConstantInt::get(
Offset->getType(), OffsetAdd);
1286 ConstantInt *DMask = cast<ConstantInt>(Args[DMaskIdx]);
1296 unsigned NewDMaskVal = 0;
1297 unsigned OrigLdStIdx = 0;
1298 for (
unsigned SrcIdx = 0; SrcIdx < 4; ++SrcIdx) {
1299 const unsigned Bit = 1 << SrcIdx;
1300 if (!!(DMaskVal & Bit)) {
1301 if (!!DemandedElts[OrigLdStIdx])
1307 if (DMaskVal != NewDMaskVal)
1308 Args[DMaskIdx] = ConstantInt::get(DMask->
getType(), NewDMaskVal);
1311 unsigned NewNumElts = DemandedElts.
popcount();
1315 if (NewNumElts >= VWidth && DemandedElts.
isMask()) {
1329 OverloadTys[0] = NewTy;
1333 for (
unsigned OrigStoreIdx = 0; OrigStoreIdx < VWidth; ++OrigStoreIdx)
1334 if (DemandedElts[OrigStoreIdx])
1337 if (NewNumElts == 1)
1350 if (NewNumElts == 1) {
1356 unsigned NewLoadIdx = 0;
1357 for (
unsigned OrigLoadIdx = 0; OrigLoadIdx < VWidth; ++OrigLoadIdx) {
1358 if (!!DemandedElts[OrigLoadIdx])
1376 SimplifyAndSetOp)
const {
1378 case Intrinsic::amdgcn_buffer_load:
1379 case Intrinsic::amdgcn_buffer_load_format:
1380 case Intrinsic::amdgcn_raw_buffer_load:
1381 case Intrinsic::amdgcn_raw_ptr_buffer_load:
1382 case Intrinsic::amdgcn_raw_buffer_load_format:
1383 case Intrinsic::amdgcn_raw_ptr_buffer_load_format:
1384 case Intrinsic::amdgcn_raw_tbuffer_load:
1385 case Intrinsic::amdgcn_raw_ptr_tbuffer_load:
1386 case Intrinsic::amdgcn_s_buffer_load:
1387 case Intrinsic::amdgcn_struct_buffer_load:
1388 case Intrinsic::amdgcn_struct_ptr_buffer_load:
1389 case Intrinsic::amdgcn_struct_buffer_load_format:
1390 case Intrinsic::amdgcn_struct_ptr_buffer_load_format:
1391 case Intrinsic::amdgcn_struct_tbuffer_load:
1392 case Intrinsic::amdgcn_struct_ptr_tbuffer_load:
1393 case Intrinsic::amdgcn_tbuffer_load:
1402 return std::nullopt;
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
static bool canContractSqrtToRsq(const FPMathOperator *SqrtOp)
Return true if it's legal to contract llvm.amdgcn.rcp(llvm.sqrt)
static Value * convertTo16Bit(Value &V, InstCombiner::BuilderTy &Builder)
static APInt trimTrailingZerosInVector(InstCombiner &IC, Value *UseV, Instruction *I)
static APInt defaultComponentBroadcast(Value *V)
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 bool matchFPExtFromF16(Value *Arg, Value *&FPExtSrc)
Match an fpext from half to float, or a constant we can convert.
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 bool canSafelyConvertTo16Bit(Value &V, bool IsFloat)
Contains the definition of a TargetInstrInfo class that is common to all AMD GPUs.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
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.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static APFloat getQNaN(const fltSemantics &Sem, bool Negative=false, const APInt *payload=nullptr)
Factory for QNaN values.
opStatus divide(const APFloat &RHS, roundingMode RM)
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
const fltSemantics & getSemantics() const
cmpResult compare(const APFloat &RHS) const
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.
unsigned popcount() const
Count the number of bits set.
unsigned getActiveBits() const
Compute the number of active bits in the value.
unsigned countr_zero() const
Count the number of trailing zero bits.
bool isMask(unsigned numBits) const
void addFnAttr(Attribute::AttrKind Kind)
Adds the attribute to the function.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
void setCalledOperand(Value *V)
void setCalledFunction(Function *Fn)
Sets the function called, including updating the function type.
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,...
static Constant * getCompare(unsigned short pred, Constant *C1, Constant *C2, bool OnlyIfReduced=false)
Return an ICmp or FCmp comparison operator constant expression.
ConstantFP - Floating Point Values [float, double].
const APFloat & getValueAPF() const
static Constant * getInfinity(Type *Ty, bool Negative=false)
static Constant * getZero(Type *Ty, bool Negative=false)
static Constant * getNaN(Type *Ty, bool Negative=false, uint64_t Payload=0)
This is the shared class of boolean and integer constants.
static 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...
static Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
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.
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 FixedVectorType * get(Type *ElementType, unsigned NumElts)
bool hasDefaultComponentZero() const
bool hasDefaultComponentBroadcast() 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
std::optional< Instruction * > instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const
bool canSimplifyLegacyMulToMul(const Instruction &I, const Value *Op0, const Value *Op1, InstCombiner &IC) const
Value * CreateFAddFMF(Value *L, Value *R, Instruction *FMFSource, const Twine &Name="")
Copy fast-math-flags from an instruction rather than using the builder's default FMF.
Value * CreateMaxNum(Value *LHS, Value *RHS, const Twine &Name="")
Create call to the maxnum intrinsic.
Value * CreateFPCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Value * CreateFMulFMF(Value *L, Value *R, Instruction *FMFSource, const Twine &Name="")
Copy fast-math-flags from an instruction rather than using the builder's default FMF.
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
Value * CreateMinNum(Value *LHS, Value *RHS, const Twine &Name="")
Create call to the minnum intrinsic.
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
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="")
LLVMContext & getContext() const
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
The core instruction combiner logic.
const DataLayout & getDataLayout() const
virtual Instruction * eraseInstFromFunction(Instruction &I)=0
Combiner aware instruction erasure.
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
const SimplifyQuery & getSimplifyQuery() const
void copyFastMathFlags(FastMathFlags FMF)
Convenience function for transferring all fast-math flag values to this instruction,...
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
const BasicBlock * getParent() const
Instruction * user_back()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
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.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static MDString * get(LLVMContext &Context, StringRef Str)
static 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...
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.
static Type * getHalfTy(LLVMContext &C)
unsigned getIntegerBitWidth() const
const fltSemantics & getFltSemantics() const
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
static IntegerType * getInt16Ty(LLVMContext &C)
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
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.
bool isVoidTy() const
Return true if this is 'void'.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
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.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_READONLY const MIMGOffsetMappingInfo * getMIMGOffsetMappingInfo(unsigned Offset)
const ImageDimIntrinsicInfo * getImageDimIntrinsicByBaseOpcode(unsigned BaseOpcode, unsigned Dim)
LLVM_READONLY const MIMGMIPMappingInfo * getMIMGMIPMappingInfo(unsigned MIP)
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.
bool getIntrinsicSignature(Intrinsic::ID, FunctionType *FT, SmallVectorImpl< Type * > &ArgTys)
Gets the type arguments of an intrinsic call by matching type contraints specified by the ....
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
bool match(Val *V, const Pattern &P)
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
OneUse_match< T > m_OneUse(const T &SubPattern)
CastInst_match< OpTy, FPExtInst > m_FPExt(const OpTy &Op)
class_match< ConstantFP > m_ConstantFP()
Match an arbitrary ConstantFP and ignore it.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
cstfp_pred_ty< is_finitenonzero > m_FiniteNonZero()
Match a finite non-zero FP constant.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > > m_ZExtOrSExt(const OpTy &Op)
cstfp_pred_ty< is_nan > m_NaN()
Match an arbitrary NaN constant.
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.
This is an optimization pass for GlobalISel generic memory operations.
int popcount(T Value) noexcept
Count the number of set bits in a value.
bool isKnownNeverInfOrNaN(const Value *V, unsigned Depth, const SimplifyQuery &SQ)
Return true if the floating-point value can never contain a NaN or infinity.
APFloat frexp(const APFloat &X, int &Exp, APFloat::roundingMode RM)
Equivalent of C standard library function.
LLVM_READONLY APFloat maxnum(const APFloat &A, const APFloat &B)
Implements IEEE-754 2019 maximumNumber semantics.
constexpr int PoisonMaskElem
Value * findScalarElement(Value *V, unsigned EltNo)
Given a vector and an element number, see if the scalar value is already around as a register,...
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
cmpResult
IEEE-754R 5.11: Floating Point Comparison Relations.
static constexpr roundingMode rmNearestTiesToEven
static constexpr roundingMode rmTowardZero
static const fltSemantics & IEEEhalf() LLVM_READNONE
SimplifyQuery getWithInstruction(const Instruction *I) const
bool isUndefValue(Value *V) const
If CanUseUndef is true, returns whether V is undef.