44#define DEBUG_TYPE "aggressive-instcombine"
50STATISTIC(NumAnyOrAllBitsSet,
"Number of any/all-bits-set patterns folded");
52 "Number of guarded rotates transformed into funnel shifts");
54 "Number of guarded funnel shifts transformed into funnel shifts");
55STATISTIC(NumPopCountRecognized,
"Number of popcount idioms recognized");
59 cl::desc(
"Max number of instructions to scan for aggressive instcombine."));
63 cl::desc(
"The maximum length of a constant string for a builtin string cmp "
64 "call eligible for inlining. The default value is 3."));
68 cl::desc(
"The maximum length of a constant string to "
69 "inline a memchr call."));
75 if (
I.getOpcode() != Instruction::PHI ||
I.getNumOperands() != 2)
89 unsigned Width = V->getType()->getScalarSizeInBits();
97 return Intrinsic::fshl;
106 return Intrinsic::fshr;
118 unsigned FunnelOp = 0, GuardOp = 1;
119 Value *P0 = Phi.getOperand(0), *P1 = Phi.getOperand(1);
120 Value *ShVal0, *ShVal1, *ShAmt;
123 (IID == Intrinsic::fshl && ShVal0 != P1) ||
124 (IID == Intrinsic::fshr && ShVal1 != P1)) {
127 (IID == Intrinsic::fshl && ShVal0 != P0) ||
128 (IID == Intrinsic::fshr && ShVal1 != P0))
130 assert((IID == Intrinsic::fshl || IID == Intrinsic::fshr) &&
131 "Pattern must match funnel shift left or right");
139 BasicBlock *GuardBB = Phi.getIncomingBlock(GuardOp);
140 BasicBlock *FunnelBB = Phi.getIncomingBlock(FunnelOp);
155 if (ShVal0 == ShVal1)
158 ++NumGuardedFunnelShifts;
162 bool IsFshl = IID == Intrinsic::fshl;
163 if (ShVal0 != ShVal1) {
165 ShVal1 = Builder.CreateFreeze(ShVal1);
167 ShVal0 = Builder.CreateFreeze(ShVal0);
184 Phi.replaceAllUsesWith(
185 Builder.CreateIntrinsic(IID, Phi.getType(), {ShVal0, ShVal1, ShAmt}));
195 Value *Root =
nullptr;
198 bool FoundAnd1 =
false;
200 MaskOps(
unsigned BitWidth,
bool MatchAnds)
201 : Mask(APInt::getZero(
BitWidth)), MatchAndChain(MatchAnds) {}
214 if (MOps.MatchAndChain) {
219 MOps.FoundAnd1 =
true;
233 const APInt *BitIndex =
nullptr;
239 MOps.Root = Candidate;
247 return MOps.Root == Candidate;
261 bool MatchAllBitsSet;
263 MatchAllBitsSet =
true;
265 MatchAllBitsSet =
false;
269 MaskOps MOps(
I.getType()->getScalarSizeInBits(), MatchAllBitsSet);
270 if (MatchAllBitsSet) {
281 Constant *Mask = ConstantInt::get(
I.getType(), MOps.Mask);
282 Value *
And = Builder.CreateAnd(MOps.Root, Mask);
283 Value *Cmp = MatchAllBitsSet ? Builder.CreateICmpEQ(
And, Mask)
284 : Builder.CreateIsNotNull(
And);
285 Value *Zext = Builder.CreateZExt(Cmp,
I.getType());
286 I.replaceAllUsesWith(Zext);
287 ++NumAnyOrAllBitsSet;
303 if (
I.getOpcode() != Instruction::LShr)
306 Type *Ty =
I.getType();
307 if (!Ty->isIntOrIntVectorTy())
310 unsigned Len = Ty->getScalarSizeInBits();
312 if (!(Len <= 128 && Len > 8 && Len % 8 == 0))
321 Value *Op0 =
I.getOperand(0);
322 Value *Op1 =
I.getOperand(1);
338 Value *Root, *SubOp1;
340 const APInt *AndMask;
344 auto CheckAndMask = [&]() {
345 if (*AndMask == Mask55)
353 APInt NeededMask = Mask55 & ~*AndMask;
359 if (CheckAndMask()) {
362 I.replaceAllUsesWith(
363 Builder.CreateIntrinsic(Intrinsic::ctpop,
I.getType(), {Root}));
364 ++NumPopCountRecognized;
386 const APInt *MinC, *MaxC;
396 if (!(*MinC + 1).isPowerOf2() || -*MaxC != *MinC + 1)
399 Type *IntTy =
I.getType();
400 Type *FpTy = In->getType();
411 SatCost +=
TTI.getCastInstrCost(Instruction::SExt, IntTy, SatTy,
418 MinMaxCost +=
TTI.getIntrinsicInstrCost(
421 MinMaxCost +=
TTI.getIntrinsicInstrCost(
425 if (SatCost >= MinMaxCost)
430 Builder.CreateIntrinsic(Intrinsic::fptosi_sat, {SatTy, FpTy}, In);
431 I.replaceAllUsesWith(Builder.CreateSExt(Sat, IntTy));
449 if (
TTI.haveFastSqrt(Ty) &&
450 (
Call->hasNoNaNs() ||
455 Builder.CreateIntrinsic(Intrinsic::sqrt, Ty, Arg,
Call,
"sqrt");
456 Call->replaceAllUsesWith(NewSqrt);
460 Call->eraseFromParent();
472 unsigned InputBits,
const APInt &GEPIdxFactor,
474 for (
unsigned Idx = 0; Idx < InputBits; Idx++) {
478 if (!
C ||
C->getValue() != Idx)
554 if (!
GEP || !
GEP->hasNoUnsignedSignedWrap())
561 unsigned BW =
DL.getIndexTypeSizeInBits(
GEP->getType());
562 APInt ModOffset(BW, 0);
564 if (!
GEP->collectOffset(
DL, BW, VarOffsets, ModOffset) ||
565 VarOffsets.
size() != 1 || ModOffset != 0)
567 auto [GepIdx, GEPScale] = VarOffsets.
front();
570 const APInt *MulConst, *ShiftConst, *AndCst =
nullptr;
583 if (InputBits != 16 && InputBits != 32 && InputBits != 64 && InputBits != 128)
586 if (!GEPScale.isIntN(InputBits) ||
589 InputBits, GEPScale.zextOrTrunc(InputBits),
DL))
594 bool DefinedForZero = ZeroTableElem->
getZExtValue() == InputBits;
599 auto Cttz =
B.CreateIntrinsic(Intrinsic::cttz, {XType}, {X1, BoolConst});
600 Value *ZExtOrTrunc =
nullptr;
602 if (DefinedForZero) {
603 ZExtOrTrunc =
B.CreateZExtOrTrunc(Cttz, AccessType);
607 auto Cmp =
B.CreateICmpEQ(X1, ConstantInt::get(XType, 0));
608 auto Select =
B.CreateSelect(Cmp,
B.CreateZExt(ZeroTableElem, XType), Cttz);
613 SelectI->setMetadata(
614 LLVMContext::MD_prof,
621 ZExtOrTrunc =
B.CreateZExtOrTrunc(
Select, AccessType);
682 bool IsBigEndian =
DL.isBigEndian();
700 if (Load1Ptr != Load2Ptr)
704 if (!
DL.typeSizeEqualsStoreSize(LI1->
getType()) ||
705 !
DL.typeSizeEqualsStoreSize(LI2->
getType()))
711 if (!Start->comesBefore(End)) {
718 unsigned NumScanned = 0;
720 make_range(Start->getIterator(), End->getIterator())) {
721 if (Inst.mayWriteToMemory() &&
isModSet(
AA.getModRefInfo(&Inst,
Loc)))
730 if (Offset2.
slt(Offset1)) {
754 uint64_t ShiftDiff = IsBigEndian ? LoadSize2 : LoadSize1;
757 if ((ShAmt2 - ShAmt1) != ShiftDiff || (Offset2 - Offset1) != PrevSize)
767 LOps.
LoadSize = LoadSize1 + LoadSize2;
798 bool Allowed =
TTI.isTypeLegal(WiderType);
802 unsigned AS = LI1->getPointerAddressSpace();
804 Allowed =
TTI.allowsMisalignedMemoryAccesses(
I.getContext(), LOps.
LoadSize,
805 AS, LI1->getAlign(), &
Fast);
806 if (!Allowed || !
Fast)
810 Value *Load1Ptr = LI1->getPointerOperand();
816 Load1Ptr = Builder.CreatePtrAdd(Load1Ptr, Builder.getInt(Offset1));
819 NewLoad = Builder.CreateAlignedLoad(WiderType, Load1Ptr, LI1->getAlign(),
820 LI1->isVolatile(),
"");
826 Value *NewOp = NewLoad;
829 NewOp = Builder.CreateZExt(NewOp, LOps.
ZextType);
834 NewOp = Builder.CreateShl(NewOp, LOps.
Shift);
835 I.replaceAllUsesWith(NewOp);
861 if (!Store || !Store->isSimple())
864 Value *StoredVal = Store->getValueOperand();
866 if (!StoredTy->
isIntegerTy() || !
DL.typeSizeEqualsStoreSize(StoredTy))
875 Value *
Ptr = Store->getPointerOperand();
876 APInt PtrOffset(
DL.getIndexTypeSizeInBits(
Ptr->getType()), 0);
877 Value *PtrBase =
Ptr->stripAndAccumulateConstantOffsets(
878 DL, PtrOffset,
true);
879 return {{PtrBase, PtrOffset, Val, ValOffset, ValWidth, Store}};
885 if (Parts.
size() < 2)
894 if (!
TTI.isTypeLegal(NewTy) ||
895 !
TTI.allowsMisalignedMemoryAccesses(Ctx, Width,
896 First.Store->getPointerAddressSpace(),
904 if (
First.ValOffset != 0)
905 Val = Builder.CreateLShr(Val,
First.ValOffset);
906 Val = Builder.CreateTrunc(Val, NewTy);
907 StoreInst *Store = Builder.CreateAlignedStore(
908 Val,
First.Store->getPointerOperand(),
First.Store->getAlign());
912 AATags = AATags.
concat(Part.Store->getAAMetadata());
913 Store->setAAMetadata(AATags);
917 Part.Store->eraseFromParent();
924 if (Parts.
size() < 2)
933 int64_t LastEndOffsetFromFirst = 0;
936 APInt PtrOffsetFromFirst = Part.PtrOffset -
First->PtrOffset;
937 int64_t ValOffsetFromFirst = Part.ValOffset -
First->ValOffset;
938 if (PtrOffsetFromFirst * 8 != ValOffsetFromFirst ||
939 LastEndOffsetFromFirst != ValOffsetFromFirst) {
941 LastEndOffsetFromFirst,
DL,
TTI);
943 LastEndOffsetFromFirst = Part.ValWidth;
947 LastEndOffsetFromFirst = ValOffsetFromFirst + Part.ValWidth;
951 LastEndOffsetFromFirst,
DL,
TTI);
958 if (
DL.isBigEndian())
963 bool MadeChange =
false;
966 if (Parts.
empty() || Part->isCompatibleWith(Parts[0])) {
981 (
I.mayReadOrWriteMemory() &&
998 if (!
I ||
I->getOpcode() != Instruction::Or || !
I->hasOneUse())
1005 Value *Op0 =
I->getOperand(0);
1012 Value *Op1 =
I->getOperand(1);
1019 if (Op0 !=
I->getOperand(0) || Op1 !=
I->getOperand(1))
1020 return Builder.CreateOr(Op0, Op1);
1036 if (OpI->getOpcode() == Instruction::Or)
1043 I.replaceAllUsesWith(Builder.CreateICmp(Pred, Res,
I.getOperand(1)));
1052static std::pair<APInt, APInt>
1054 unsigned BW =
DL.getIndexTypeSizeInBits(PtrOp->
getType());
1055 std::optional<APInt> Stride;
1056 APInt ModOffset(BW, 0);
1061 if (!
GEP->collectOffset(
DL, BW, VarOffsets, ModOffset))
1064 for (
auto [V, Scale] : VarOffsets) {
1066 if (!
GEP->hasNoUnsignedSignedWrap())
1075 PtrOp =
GEP->getPointerOperand();
1085 ModOffset = ModOffset.
srem(*Stride);
1087 ModOffset += *Stride;
1089 return {*Stride, ModOffset};
1096 if (!LI || LI->isVolatile())
1101 auto *PtrOp = LI->getPointerOperand();
1103 if (!GV || !GV->isConstant() || !GV->hasDefinitiveInitializer())
1108 uint64_t GVSize =
DL.getTypeAllocSize(
C->getType());
1109 if (!GVSize || 4096 < GVSize)
1112 Type *LoadTy = LI->getType();
1113 unsigned BW =
DL.getIndexTypeSizeInBits(PtrOp->getType());
1119 if (
auto LA = LI->getAlign();
1120 LA <= GV->
getAlign().valueOrOne() && Stride.getZExtValue() < LA.value()) {
1121 ConstOffset =
APInt(BW, 0);
1122 Stride =
APInt(BW, LA.value());
1129 unsigned E = GVSize -
DL.getTypeStoreSize(LoadTy);
1130 for (; ConstOffset.getZExtValue() <=
E; ConstOffset += Stride)
1134 I.replaceAllUsesWith(Ca);
1140class StrNCmpInliner {
1142 StrNCmpInliner(CallInst *CI,
LibFunc Func, DomTreeUpdater *DTU,
1143 const DataLayout &DL)
1144 : CI(CI), Func(Func), DTU(DTU), DL(DL) {}
1146 bool optimizeStrNCmp();
1149 void inlineCompare(
Value *
LHS, StringRef
RHS, uint64_t
N,
bool Swapped);
1153 DomTreeUpdater *DTU;
1154 const DataLayout &DL;
1187bool StrNCmpInliner::optimizeStrNCmp() {
1200 StringRef Str1, Str2;
1203 if (HasStr1 == HasStr2)
1207 StringRef Str = HasStr1 ? Str1 : Str2;
1208 Value *StrP = HasStr1 ? Str2P : Str1P;
1210 size_t Idx = Str.find(
'\0');
1212 if (Func == LibFunc_strncmp) {
1214 N = std::min(
N, ConstInt->getZExtValue());
1224 bool CanBeNull =
false, CanBeFreed =
false;
1227 inlineCompare(StrP, Str,
N, HasStr1);
1265void StrNCmpInliner::inlineCompare(
Value *
LHS, StringRef
RHS, uint64_t
N,
1282 for (uint64_t
I = 0;
I <
N; ++
I)
1289 B.SetInsertPoint(BBNE);
1294 for (uint64_t i = 0; i <
N; ++i) {
1295 B.SetInsertPoint(BBSubs[i]);
1297 B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(),
1298 B.CreateInBoundsPtrAdd(
Base,
B.getInt64(i))),
1301 ConstantInt::get(CI->
getType(),
static_cast<unsigned char>(
RHS[i]));
1302 Value *
Sub = Swapped ?
B.CreateSub(VR, VL) :
B.CreateSub(VL, VR);
1304 BranchInst *CondBrInst =
B.CreateCondBr(
1305 B.CreateICmpNE(
Sub, ConstantInt::get(CI->
getType(), 0)), BBNE,
1309 assert(
F &&
"Instruction does not belong to a function!");
1310 std::optional<Function::ProfileCount>
EC =
F->getEntryCount();
1311 if (EC &&
EC->getCount() > 0)
1317 Phi->addIncoming(
Sub, BBSubs[i]);
1325 Updates.
push_back({DominatorTree::Insert, BBCI, BBSubs[0]});
1326 for (uint64_t i = 0; i <
N; ++i) {
1328 Updates.
push_back({DominatorTree::Insert, BBSubs[i], BBSubs[i + 1]});
1329 Updates.
push_back({DominatorTree::Insert, BBSubs[i], BBNE});
1331 Updates.
push_back({DominatorTree::Insert, BBNE, BBTail});
1332 Updates.
push_back({DominatorTree::Delete, BBCI, BBTail});
1350 uint64_t Val = ConstInt->getZExtValue();
1373 Type *IndexTy =
DL.getIndexType(
Call->getType());
1377 Call->getContext(),
"memchr.success", BB->
getParent(), BBNext);
1387 ConstantInt *CaseVal = ConstantInt::get(ByteTy, Str[
I]);
1388 if (!Cases.
insert(CaseVal).second)
1393 SI->addCase(CaseVal, BBCase);
1395 IndexPHI->
addIncoming(ConstantInt::get(IndexTy,
I), BBCase);
1406 PHI->addIncoming(FirstOccursLocation, BBSuccess);
1408 Call->replaceAllUsesWith(
PHI);
1409 Call->eraseFromParent();
1420 bool &MadeCFGChange) {
1423 if (!CI || CI->isNoBuiltin())
1426 Function *CalledFunc = CI->getCalledFunction();
1442 case LibFunc_strcmp:
1443 case LibFunc_strncmp:
1444 if (StrNCmpInliner(CI, LF, &DTU,
DL).optimizeStrNCmp()) {
1445 MadeCFGChange =
true;
1449 case LibFunc_memchr:
1451 MadeCFGChange =
true;
1467 bool MadeChange =
false;
1512 bool MadeChange =
false;
1515 MadeChange |= TIC.
run(
F);
1527 bool MadeCFGChange =
false;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static bool tryToRecognizePopCount(Instruction &I)
static bool foldSqrt(CallInst *Call, LibFunc Func, TargetTransformInfo &TTI, TargetLibraryInfo &TLI, AssumptionCache &AC, DominatorTree &DT)
Try to replace a mathlib call to sqrt with the LLVM intrinsic.
static bool foldAnyOrAllBitsSet(Instruction &I)
Match patterns that correspond to "any-bits-set" and "all-bits-set".
static cl::opt< unsigned > MemChrInlineThreshold("memchr-inline-threshold", cl::init(3), cl::Hidden, cl::desc("The maximum length of a constant string to " "inline a memchr call."))
static bool tryToFPToSat(Instruction &I, TargetTransformInfo &TTI)
Fold smin(smax(fptosi(x), C1), C2) to llvm.fptosi.sat(x), providing C1 and C2 saturate the value of t...
static cl::opt< unsigned > StrNCmpInlineThreshold("strncmp-inline-threshold", cl::init(3), cl::Hidden, cl::desc("The maximum length of a constant string for a builtin string cmp " "call eligible for inlining. The default value is 3."))
static bool matchAndOrChain(Value *V, MaskOps &MOps)
This is a recursive helper for foldAnyOrAllBitsSet() that walks through a chain of 'and' or 'or' inst...
static bool foldMemChr(CallInst *Call, DomTreeUpdater *DTU, const DataLayout &DL)
Convert memchr with a small constant string into a switch.
static Value * optimizeShiftInOrChain(Value *V, IRBuilder<> &Builder)
Combine away instructions providing they are still equivalent when compared against 0.
static bool foldConsecutiveLoads(Instruction &I, const DataLayout &DL, TargetTransformInfo &TTI, AliasAnalysis &AA, const DominatorTree &DT)
static bool foldGuardedFunnelShift(Instruction &I, const DominatorTree &DT)
Match a pattern for a bitwise funnel/rotate operation that partially guards against undefined behavio...
static bool tryToRecognizeTableBasedCttz(Instruction &I, const DataLayout &DL)
static bool mergePartStores(SmallVectorImpl< PartStore > &Parts, const DataLayout &DL, TargetTransformInfo &TTI)
static bool mergeConsecutivePartStores(ArrayRef< PartStore > Parts, unsigned Width, const DataLayout &DL, TargetTransformInfo &TTI)
static cl::opt< unsigned > MaxInstrsToScan("aggressive-instcombine-max-scan-instrs", cl::init(64), cl::Hidden, cl::desc("Max number of instructions to scan for aggressive instcombine."))
static bool foldLoadsRecursive(Value *V, LoadOps &LOps, const DataLayout &DL, AliasAnalysis &AA)
static bool foldICmpOrChain(Instruction &I, const DataLayout &DL, TargetTransformInfo &TTI, AliasAnalysis &AA, const DominatorTree &DT)
static bool isCTTZTable(Constant *Table, const APInt &Mul, const APInt &Shift, const APInt &AndMask, Type *AccessTy, unsigned InputBits, const APInt &GEPIdxFactor, const DataLayout &DL)
static std::optional< PartStore > matchPartStore(Instruction &I, const DataLayout &DL)
static bool foldConsecutiveStores(BasicBlock &BB, const DataLayout &DL, TargetTransformInfo &TTI, AliasAnalysis &AA)
static std::pair< APInt, APInt > getStrideAndModOffsetOfGEP(Value *PtrOp, const DataLayout &DL)
static bool foldPatternedLoads(Instruction &I, const DataLayout &DL)
If C is a constant patterned array and all valid loaded results for given alignment are same to a con...
static bool foldLibCalls(Instruction &I, TargetTransformInfo &TTI, TargetLibraryInfo &TLI, AssumptionCache &AC, DominatorTree &DT, const DataLayout &DL, bool &MadeCFGChange)
static bool foldUnusualPatterns(Function &F, DominatorTree &DT, TargetTransformInfo &TTI, TargetLibraryInfo &TLI, AliasAnalysis &AA, AssumptionCache &AC, bool &MadeCFGChange)
This is the entry point for folds that could be implemented in regular InstCombine,...
AggressiveInstCombiner - Combine expression patterns to form expressions with fewer,...
This is the interface for LLVM's primary stateless and local alias analysis.
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")
static bool runImpl(Function &F, const TargetLowering &TLI, AssumptionCache *AC)
This is the interface for a simple mod/ref and alias analysis over globals.
static MaybeAlign getAlign(Value *Ptr)
static Instruction * matchFunnelShift(Instruction &Or, InstCombinerImpl &IC)
Match UB-safe variants of the funnel shift intrinsic.
This file contains the declarations for profiling metadata utility functions.
static const MCExpr * MaskShift(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
A manager for alias analyses.
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
uint64_t getZExtValue() const
Get zero extended value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool isNegative() const
Determine sign of this APInt.
static LLVM_ABI APInt getSplat(unsigned NewLen, const APInt &V)
Return a value containing V broadcasted over NewLen bits.
LLVM_ABI APInt srem(const APInt &RHS) const
Function for signed remainder operation.
APInt shl(unsigned shiftAmt) const
Left-shift function.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
bool slt(const APInt &RHS) const
Signed less than comparison.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
front - Get the first element.
size_t size() const
size - Get the array size.
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
ModRefInfo getModRefInfo(const Instruction *I, const std::optional< MemoryLocation > &OptLoc)
Represents analyses that only rely on functions' control flow.
Value * getArgOperand(unsigned i) const
This class represents a function call, abstracting a target machine's calling convention.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
This is an important base class in LLVM.
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.
Analysis pass which computes a DominatorTree.
static constexpr UpdateKind Insert
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
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.
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool hasInitializer() const
Definitions have initializers, declarations don't.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
static bool isEquality(Predicate P)
Return true if this predicate is either EQ or NE.
void SetCurrentDebugLocation(DebugLoc L)
Set location information used by debugging information.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
SwitchInst * CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases=10, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a switch instruction with the specified value, default dest, and with a hint for the number of...
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
BranchInst * CreateBr(BasicBlock *Dest)
Create an unconditional 'br label X' instruction.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateInBoundsPtrAdd(Value *Ptr, Value *Offset, const Twine &Name="")
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI void setAAMetadata(const AAMDNodes &N)
Sets the AA metadata on this instruction from the AAMDNodes structure.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI AAMDNodes getAAMetadata() const
Returns the AA metadata for this instruction.
Class to represent integer types.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
Value * getPointerOperand()
LLVM_ABI MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
std::pair< KeyT, ValueT > & front()
Representation for a specific memory location.
static LLVM_ABI MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
static MemoryLocation getBeforeOrAfter(const Value *Ptr, const AAMDNodes &AATags=AAMDNodes())
Return a location that may access any location before or after Ptr, while remaining within the underl...
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
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.
An instruction for storing to memory.
StringRef - Represent a constant reference to a string, i.e.
static constexpr size_t npos
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
bool run(Function &F)
Perform TruncInst pattern optimization on given function.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI uint64_t getPointerDereferenceableBytes(const DataLayout &DL, bool &CanBeNull, bool &CanBeFreed) const
Returns the number of bytes known to be dereferenceable for the pointer value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
const ParentTy * getParent() const
Abstract Attribute helper functions.
LLVM_ABI APInt GreatestCommonDivisor(APInt A, APInt B)
Compute GCD of two unsigned APInt values.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
ShiftLike_match< LHS, Instruction::LShr > m_LShrOrSelf(const LHS &L, uint64_t &R)
Matches lshr L, ConstShAmt or L itself (R will be set to zero in this case).
match_combine_or< CastInst_match< OpTy, CastInst >, OpTy > m_CastOrSelf(const OpTy &Op)
Matches any cast or self. Used to ignore casts.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
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.
MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > m_SMin(const LHS &L, const RHS &R)
ShiftLike_match< LHS, Instruction::Shl > m_ShlOrSelf(const LHS &L, uint64_t &R)
Matches shl L, ConstShAmt or L itself (R will be set to zero in this case).
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
specific_bbval m_SpecificBB(BasicBlock *BB)
Match a specific basic block value.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoSignedWrap > m_NSWShl(const LHS &L, const RHS &R)
SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWShl(const LHS &L, const RHS &R)
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
CastInst_match< OpTy, FPToSIInst > m_FPToSI(const OpTy &Op)
MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty > m_SMax(const LHS &L, const RHS &R)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
initializer< Ty > init(const Ty &Val)
NodeAddr< PhiNode * > Phi
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
FunctionAddr VTableAddr Value
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isOnlyUsedInZeroComparison(const Instruction *CxtI)
LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I, Function &F, StringRef PassName)
Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch weights in the new instruct...
LLVM_ABI bool getConstantStringInfo(const Value *V, StringRef &Str, bool TrimAtNul=true)
This function computes the length of a null-terminated C string pointed to by V.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetLibraryInfo *TLI=nullptr)
Scan the specified basic block and try to simplify any instructions in it and recursively delete dead...
LLVM_ABI void setExplicitlyUnknownBranchWeights(Instruction &I, StringRef PassName)
Specify that the branch weights for this terminator cannot be known at compile time.
LLVM_ABI bool MaskedValueIsZero(const Value *V, const APInt &Mask, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if 'V & Mask' is known to be zero.
LLVM_ABI bool isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI, LibFunc TheLibFunc)
Check whether the library function is available on target and also that it in the current Module is a...
auto dyn_cast_or_null(const Y &Val)
auto reverse(ContainerTy &&C)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool isModSet(const ModRefInfo MRI)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isModOrRefSet(const ModRefInfo MRI)
LLVM_ABI Constant * ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset, const DataLayout &DL)
Extract value of C at the given Offset reinterpreted as Ty.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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...
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
@ Sub
Subtraction of integers.
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="", bool Before=false)
Split the specified block at the specified instruction.
cl::opt< bool > ProfcheckDisableMetadataFixes("profcheck-disable-metadata-fixes", cl::Hidden, cl::init(false), cl::desc("Disable metadata propagation fixes discovered through Issue #147390"))
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
LLVM_ABI bool cannotBeOrderedLessThanZero(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if we can prove that the specified FP value is either NaN or never less than -0....
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
ValWidth bits starting at ValOffset of Val stored at PtrBase+PtrOffset.
bool operator<(const PartStore &Other) const
bool isCompatibleWith(const PartStore &Other) const
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
LLVM_ABI AAMDNodes concat(const AAMDNodes &Other) const
Determine the best AAMDNodes after concatenating two different locations together.
A MapVector that performs no allocations if smaller than a certain size.