46#define DEBUG_TYPE "aggressive-instcombine"
48STATISTIC(NumAnyOrAllBitsSet,
"Number of any/all-bits-set patterns folded");
50 "Number of guarded rotates transformed into funnel shifts");
52 "Number of guarded funnel shifts transformed into funnel shifts");
53STATISTIC(NumPopCountRecognized,
"Number of popcount idioms recognized");
55 "Number of select-based split cttz patterns folded");
57 "Number of select-based split ctlz patterns folded");
58STATISTIC(NumMemSetsGuarded,
"Number of memsets guarded for a zero length");
60 "Number of low-bits mask table loads folded to (1 << i) - 1");
64 cl::desc(
"Max number of instructions to scan for aggressive instcombine."));
68 cl::desc(
"The maximum length of a constant string for a builtin string cmp "
69 "call eligible for inlining. The default value is 3."));
73 cl::desc(
"The maximum length of a constant string to "
74 "inline a memchr call."));
98 unsigned FullWidth = HalfWidth * 2;
121 if (!
match(HiCttzArg,
127 Value *CttzWide = Builder.CreateIntrinsic(
128 Intrinsic::cttz, {SrcVal->
getType()}, {SrcVal, Builder.getFalse()});
129 Value *Trunc = Builder.CreateTrunc(CttzWide, HalfTy);
131 I.replaceAllUsesWith(Trunc);
132 ++NumSelectCTTZFolded;
155 unsigned FullWidth = HalfWidth * 2;
173 if (!
match(HiCtlzArg,
192 Value *CtlzWide = Builder.CreateIntrinsic(
193 Intrinsic::ctlz, {SrcVal->
getType()}, {SrcVal, Builder.getFalse()});
194 Value *Trunc = Builder.CreateTrunc(CtlzWide, HalfTy);
196 I.replaceAllUsesWith(Trunc);
197 ++NumSelectCTLZFolded;
209 Type *Ty =
I.getType();
210 if (!Ty->isIntegerTy())
216 if (Ty->getIntegerBitWidth() <= 2)
237 if (
I.getOpcode() != Instruction::PHI ||
I.getNumOperands() != 2)
251 unsigned Width = V->getType()->getScalarSizeInBits();
259 return Intrinsic::fshl;
268 return Intrinsic::fshr;
280 unsigned FunnelOp = 0, GuardOp = 1;
281 Value *P0 = Phi.getOperand(0), *P1 = Phi.getOperand(1);
282 Value *ShVal0, *ShVal1, *ShAmt;
285 (IID == Intrinsic::fshl && ShVal0 != P1) ||
286 (IID == Intrinsic::fshr && ShVal1 != P1)) {
289 (IID == Intrinsic::fshl && ShVal0 != P0) ||
290 (IID == Intrinsic::fshr && ShVal1 != P0))
292 assert((IID == Intrinsic::fshl || IID == Intrinsic::fshr) &&
293 "Pattern must match funnel shift left or right");
301 BasicBlock *GuardBB = Phi.getIncomingBlock(GuardOp);
302 BasicBlock *FunnelBB = Phi.getIncomingBlock(FunnelOp);
317 if (ShVal0 == ShVal1)
320 ++NumGuardedFunnelShifts;
324 bool IsFshl = IID == Intrinsic::fshl;
325 if (ShVal0 != ShVal1) {
327 ShVal1 = Builder.CreateFreeze(ShVal1);
329 ShVal0 = Builder.CreateFreeze(ShVal0);
346 Phi.replaceAllUsesWith(
347 Builder.CreateIntrinsic(IID, Phi.getType(), {ShVal0, ShVal1, ShAmt}));
357 Value *Root =
nullptr;
360 bool FoundAnd1 =
false;
362 MaskOps(
unsigned BitWidth,
bool MatchAnds)
363 : Mask(APInt::getZero(
BitWidth)), MatchAndChain(MatchAnds) {}
376 if (MOps.MatchAndChain) {
381 MOps.FoundAnd1 =
true;
395 const APInt *BitIndex =
nullptr;
401 MOps.Root = Candidate;
409 return MOps.Root == Candidate;
423 bool MatchAllBitsSet;
426 if (
I.getType()->isIntOrIntVectorTy(1)) {
428 MatchAllBitsSet =
true;
430 MatchAllBitsSet =
false;
438 MatchAllBitsSet =
true;
442 MatchAllBitsSet =
false;
447 Type *Ty =
X->getType();
449 MaskOps MOps(Ty->getScalarSizeInBits(), MatchAllBitsSet);
451 (MatchAllBitsSet && !MatchTrunc && !MOps.FoundAnd1))
457 Constant *Mask = ConstantInt::get(Ty, MOps.Mask);
458 Value *
And = Builder.CreateAnd(MOps.Root, Mask);
459 Value *Cmp = MatchAllBitsSet ? Builder.CreateICmpEQ(
And, Mask)
460 : Builder.CreateIsNotNull(
And);
461 Value *Zext = MatchTrunc ? Cmp : Builder.CreateZExt(Cmp, Ty);
462 I.replaceAllUsesWith(Zext);
463 ++NumAnyOrAllBitsSet;
474 Builder.CreateIntrinsic(Intrinsic::ctpop, Root->
getType(), {Root});
475 I.replaceAllUsesWith(Builder.CreateZExtOrTrunc(NewVal,
I.getType()));
476 ++NumPopCountRecognized;
498 APInt NegThree(Len, -3,
true);
513 const APInt *AndMask;
521 if (*AndMask != Mask55) {
525 APInt NeededMask = Mask55 & ~*AndMask;
545 if (
I.getOpcode() != Instruction::LShr)
548 Type *Ty =
I.getType();
549 if (!Ty->isIntOrIntVectorTy())
552 unsigned Len = Ty->getScalarSizeInBits();
555 if (Len > 128 || Len <= 8 || Len % 8 != 0)
560 Value *Op0 =
I.getOperand(0);
561 Value *Op1 =
I.getOperand(1);
599 if (
I.getOpcode() != Instruction::Add)
602 Type *Ty =
I.getType();
603 if (!Ty->isIntOrIntVectorTy())
606 unsigned Len = Ty->getScalarSizeInBits();
607 if (Len > 64 || Len <= 8 || Len % 8 != 0)
623 auto isValidNarrowedMask = [&](
const APInt &CapturedMask,
624 const APInt &ExpectedMask,
625 Value *Operand) ->
bool {
626 if (CapturedMask == ExpectedMask)
630 APInt NeededMask = ExpectedMask & ~CapturedMask;
636 auto narrowAddPairMasksOk = [&](
const APInt &BaseMask,
unsigned ShiftAmt,
638 const APInt &AndMask2) ->
bool {
639 if (!AndMask1.isSubsetOf(BaseMask) || !AndMask2.isSubsetOf(BaseMask))
641 APInt NeededShifted = (BaseMask & ~AndMask1).shl(ShiftAmt);
642 APInt NeededUnshifted = BaseMask & ~AndMask2;
643 APInt AllNeeded = NeededShifted | NeededUnshifted;
649 for (
unsigned I = Len;
I >= 8;
I =
I / 2) {
651 const APInt *AndMask1 =
nullptr, *AndMask2 =
nullptr;
659 if (!narrowAddPairMasksOk(Mask,
I / 2, ShiftOp, *AndMask1, *AndMask2))
664 else if (
match(Start,
667 if (!isValidNarrowedMask(*AndMask1, Mask, ShiftOp))
675 const APInt *AndMask1 =
nullptr, *AndMask2 =
nullptr;
680 if (!narrowAddPairMasksOk(Mask33, 2, ShiftOp, *AndMask1, *AndMask2))
692 if (!narrowAddPairMasksOk(Mask55, 1, Root, *AndMask1, *AndMask2))
719 if (
I.getOpcode() != Instruction::And)
722 Type *Ty =
I.getType();
723 if (!Ty->isIntOrIntVectorTy())
726 unsigned Len = Ty->getScalarSizeInBits();
733 const APInt *MaskRes;
748 if (Len > 64 || Len <= 8 || Len % 8 != 0)
756 unsigned NumLenBits =
Log2_32(Len) + 1;
767 for (
unsigned I = Len;
I >= 16;
I =
I / 2) {
796 const APInt *MinC, *MaxC;
806 if (!(*MinC + 1).isPowerOf2() || -*MaxC != *MinC + 1)
809 Type *IntTy =
I.getType();
810 Type *FpTy = In->getType();
821 SatCost +=
TTI.getCastInstrCost(Instruction::SExt, IntTy, SatTy,
828 MinMaxCost +=
TTI.getIntrinsicInstrCost(
831 MinMaxCost +=
TTI.getIntrinsicInstrCost(
835 if (SatCost >= MinMaxCost)
840 Builder.CreateIntrinsic(Intrinsic::fptosi_sat, {SatTy, FpTy}, In);
841 I.replaceAllUsesWith(Builder.CreateSExt(Sat, IntTy));
859 if (
TTI.haveFastSqrt(Ty) &&
860 (
Call->hasNoNaNs() ||
865 Builder.CreateIntrinsic(Intrinsic::sqrt, Ty, Arg,
Call,
"sqrt");
866 Call->replaceAllUsesWith(NewSqrt);
870 Call->eraseFromParent();
882 unsigned InputBits,
const APInt &GEPIdxFactor,
884 for (
unsigned Idx = 0; Idx < InputBits; Idx++) {
889 if (!
C ||
C->getValue() != Idx)
961 const APInt &GEPScale,
964 const APInt *MulConst, *ShiftConst, *AndCst =
nullptr;
977 if (InputBits != 16 && InputBits != 32 && InputBits != 64 && InputBits != 128)
980 if (!GEPScale.
isIntN(InputBits) ||
988 bool DefinedForZero = ZeroTableElem->
equalsInt(InputBits);
993 auto Cttz =
B.CreateIntrinsic(Intrinsic::cttz, {XType}, {X1, BoolConst});
994 Value *Res =
B.CreateZExtOrTrunc(Cttz, AccessType);
996 if (!DefinedForZero) {
1002 auto Cmp =
B.CreateICmpEQ(X1, ConstantInt::get(XType, 0));
1003 Res =
B.CreateSelect(Cmp, ZeroTableElem, Res);
1007 SelectI->setMetadata(
1008 LLVMContext::MD_prof,
1038 unsigned AccessSize =
DL.getTypeStoreSize(AccessType);
1039 if (GEPScale != AccessSize)
1041 uint64_t NumEntries = TableSize / AccessSize;
1057 Type *AccessTy,
unsigned InputBits,
1059 for (
unsigned Idx = 0; Idx < InputBits; Idx++) {
1063 if (!
C ||
C->getValue() != Idx)
1158 const APInt &GEPScale,
1162 const APInt *MulConst, *ShiftConst;
1174 bool IsolatedMSB =
false;
1181 unsigned InputBits =
X->getType()->getScalarSizeInBits();
1182 if (InputBits != 16 && InputBits != 32 && InputBits != 64 && InputBits != 128)
1187 if (*ShiftConst != InputBits -
Log2_32(InputBits))
1191 for (
unsigned ShiftAmt = InputBits / 2; ShiftAmt != 0; ShiftAmt /= 2) {
1199 if (!GEPScale.
isIntN(InputBits))
1213 AccessType, InputBits, GEPScale.
zextOrTrunc(InputBits),
1224 Type *XType =
X->getType();
1230 Intrinsic::ctlz, XType,
1237 Constant *InputBitsM1 = ConstantInt::get(XType, InputBits - 1);
1242 B.CreateIntrinsic(Intrinsic::ctlz, {XType}, {
X,
B.getFalse()});
1243 Result =
B.CreateAnd(
B.CreateNot(Ctlz), InputBitsM1);
1245 Value *Ctlz =
B.CreateIntrinsic(Intrinsic::ctlz, {XType}, {
X, BoolConst});
1246 Value *
Sub =
B.CreateSub(InputBitsM1, Ctlz);
1249 Value *Cmp =
B.CreateICmpEQ(
X, ConstantInt::get(XType, 0));
1251 B.CreateSelect(Cmp,
B.CreateZExt(ZeroTableElem, XType),
Sub);
1255 SelectI->setMetadata(
1256 LLVMContext::MD_prof,
1262 Value *ZExtOrTrunc =
B.CreateZExtOrTrunc(Result, AccessType);
1283 const APInt &GEPScale,
1292 if (!ArrTy || ArrTy->getElementType() != AccessType ||
1297 uint64_t EltBytes =
DL.getTypeAllocSize(AccessType).getFixedValue();
1305 if (!
DL.fitsInLegalInteger(EltBits))
1315 if (!
GEP->isInBounds())
1322 if (
K == 0 ||
K > EltBits)
1327 if (GEPScale != EltBytes)
1343 Value *Idx = Builder.CreateZExtOrTrunc(GepIdx, AccessType);
1345 Builder.CreateSub(Builder.CreateShl(ConstantInt::get(AccessType, 1), Idx),
1346 ConstantInt::get(AccessType, 1));
1348 ++NumTableBasedLowBitsMask;
1367 if (!
GEP || !
GEP->hasNoUnsignedSignedWrap())
1375 unsigned BW =
DL.getIndexTypeSizeInBits(
GEP->getType());
1376 APInt ModOffset(BW, 0);
1378 if (!
GEP->collectOffset(
DL, BW, VarOffsets, ModOffset) ||
1379 VarOffsets.
size() != 1 || ModOffset != 0)
1381 auto [GepIdx, GEPScale] = VarOffsets.
front();
1424 if (!IsRoot && !V->hasOneUse())
1456 bool IsBigEndian =
DL.isBigEndian();
1460 APInt Offset1(
DL.getIndexTypeSizeInBits(Load1Ptr->
getType()), 0);
1466 APInt Offset2(
DL.getIndexTypeSizeInBits(Load2Ptr->
getType()), 0);
1474 if (Load1Ptr != Load2Ptr)
1478 if (!
DL.typeSizeEqualsStoreSize(LI1->
getType()) ||
1479 !
DL.typeSizeEqualsStoreSize(LI2->
getType()))
1485 if (!Start->comesBefore(
End)) {
1500 unsigned NumScanned = 0;
1503 if (Inst.mayWriteToMemory() &&
isModSet(
AA.getModRefInfo(&Inst,
Loc)))
1512 if (Offset2.
slt(Offset1)) {
1536 uint64_t ShiftDiff = IsBigEndian ? LoadSize2 : LoadSize1;
1539 if ((ShAmt2 - ShAmt1) != ShiftDiff || (Offset2 - Offset1) != PrevSize)
1545 if (LoadSize1 + LoadSize2 >
X->getType()->getScalarSizeInBits())
1555 LOps.
LoadSize = LoadSize1 + LoadSize2;
1562 LOps.
Shift = ShAmt1;
1590 unsigned AS = LI1->getPointerAddressSpace();
1592 Allowed =
TTI.allowsMisalignedMemoryAccesses(
I.getContext(), LOps.
LoadSize,
1593 AS, LI1->getAlign(), &
Fast);
1594 if (!Allowed || !
Fast)
1598 Value *Load1Ptr = LI1->getPointerOperand();
1601 APInt Offset1(
DL.getIndexTypeSizeInBits(Load1Ptr->
getType()), 0);
1604 Load1Ptr = Builder.CreatePtrAdd(Load1Ptr, Builder.getInt(Offset1));
1608 NewLoad = Builder.CreateAlignedLoad(WiderType, Load1Ptr, LI1->getAlign(),
1609 LI1->isVolatile(),
"");
1615 Value *NewOp = NewLoad;
1617 NewOp = Builder.CreateZExt(NewOp, LOps.
ZextType);
1622 NewOp = Builder.CreateShl(NewOp, LOps.
Shift);
1623 I.replaceAllUsesWith(NewOp);
1641 Store->getPointerAddressSpace() ==
1642 Other.Store->getPointerAddressSpace();
1654 return std::nullopt;
1658 if (!StoredTy->
isIntegerTy() || !
DL.typeSizeEqualsStoreSize(StoredTy))
1659 return std::nullopt;
1665 return std::nullopt;
1670 DL, PtrOffset,
true);
1671 return {{PtrBase, PtrOffset, Val, ValOffset, ValWidth,
Store}};
1677 if (Parts.
size() < 2)
1688 !
TTI.allowsMisalignedMemoryAccesses(Ctx, Width,
1689 First.Store->getPointerAddressSpace(),
1698 if (
First.ValOffset != 0)
1699 Val = Builder.CreateLShr(Val,
First.ValOffset);
1700 Val = Builder.CreateZExtOrTrunc(Val, NewTy);
1702 Val,
First.Store->getPointerOperand(),
First.Store->getAlign());
1711 AATags = AATags.
concat(Part.Store->getAAMetadata());
1713 DbgLocs.
push_back(Part.Store->getDebugLoc());
1715 Store->setAAMetadata(AATags);
1716 Store->mergeDIAssignID(Stores);
1721 Part.Store->eraseFromParent();
1728 if (Parts.
size() < 2)
1737 int64_t LastEndOffsetFromFirst = 0;
1740 APInt PtrOffsetFromFirst = Part.PtrOffset -
First->PtrOffset;
1741 int64_t ValOffsetFromFirst = Part.ValOffset -
First->ValOffset;
1742 if (PtrOffsetFromFirst * 8 != ValOffsetFromFirst ||
1743 LastEndOffsetFromFirst != ValOffsetFromFirst) {
1745 LastEndOffsetFromFirst,
DL,
TTI);
1747 LastEndOffsetFromFirst = Part.ValWidth;
1751 LastEndOffsetFromFirst = ValOffsetFromFirst + Part.ValWidth;
1755 LastEndOffsetFromFirst,
DL,
TTI);
1762 if (
DL.isBigEndian())
1767 bool MadeChange =
false;
1770 if (Parts.
empty() || Part->isCompatibleWith(Parts[0])) {
1785 (
I.mayReadOrWriteMemory() &&
1802 if (!
I ||
I->getOpcode() != Instruction::Or || !
I->hasOneUse())
1809 Value *Op0 =
I->getOperand(0);
1816 Value *Op1 =
I->getOperand(1);
1823 if (Op0 !=
I->getOperand(0) || Op1 !=
I->getOperand(1))
1824 return Builder.CreateOr(Op0, Op1);
1840 if (OpI->getOpcode() == Instruction::Or)
1847 I.replaceAllUsesWith(Builder.CreateICmp(Pred, Res,
I.getOperand(1)));
1856static std::pair<APInt, APInt>
1858 unsigned BW =
DL.getIndexTypeSizeInBits(PtrOp->
getType());
1859 std::optional<APInt> Stride;
1860 APInt ModOffset(BW, 0);
1865 if (!
GEP->collectOffset(
DL, BW, VarOffsets, ModOffset))
1868 for (
auto [V, Scale] : VarOffsets) {
1870 if (!
GEP->hasNoUnsignedSignedWrap())
1879 PtrOp =
GEP->getPointerOperand();
1889 ModOffset = ModOffset.
srem(*Stride);
1891 ModOffset += *Stride;
1893 return {*Stride, ModOffset};
1900 if (!LI || LI->isVolatile())
1905 auto *PtrOp = LI->getPointerOperand();
1907 if (!GV || !GV->isConstant() || !GV->hasDefinitiveInitializer())
1912 uint64_t GVSize =
DL.getTypeAllocSize(
C->getType());
1913 if (!GVSize || 4096 < GVSize)
1916 Type *LoadTy = LI->getType();
1917 unsigned BW =
DL.getIndexTypeSizeInBits(PtrOp->getType());
1923 if (
auto LA = LI->getAlign();
1924 LA <= GV->
getAlign().valueOrOne() && Stride.getZExtValue() < LA.value()) {
1925 ConstOffset =
APInt(BW, 0);
1926 Stride =
APInt(BW, LA.value());
1933 unsigned E = GVSize -
DL.getTypeStoreSize(LoadTy);
1934 for (; ConstOffset.getZExtValue() <=
E; ConstOffset += Stride)
1938 I.replaceAllUsesWith(Ca);
1944class StrNCmpInliner {
1946 StrNCmpInliner(CallInst *CI, LibFunc Func, DomTreeUpdater *DTU,
1947 const DataLayout &DL)
1948 : CI(CI), Func(Func), DTU(DTU), DL(DL) {}
1950 bool optimizeStrNCmp();
1957 DomTreeUpdater *DTU;
1958 const DataLayout &DL;
1991bool StrNCmpInliner::optimizeStrNCmp() {
2004 StringRef Str1, Str2;
2007 if (HasStr1 == HasStr2)
2011 StringRef Str = HasStr1 ? Str1 : Str2;
2012 Value *StrP = HasStr1 ? Str2P : Str1P;
2014 size_t Idx = Str.find(
'\0');
2016 if (Func == LibFunc_strncmp) {
2018 N = std::min(
N, ConstInt->getZExtValue());
2028 bool CanBeNull =
false;
2032 inlineCompare(StrP, Str,
N, HasStr1);
2094 B.SetInsertPoint(BBNE);
2100 B.SetInsertPoint(BBSubs[i]);
2102 B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(),
2103 B.CreateInBoundsPtrAdd(
Base,
B.getInt64(i))),
2106 ConstantInt::get(CI->
getType(),
static_cast<unsigned char>(
RHS[i]));
2107 Value *
Sub = Swapped ?
B.CreateSub(VR, VL) :
B.CreateSub(VL, VR);
2109 CondBrInst *CondBrInst =
B.CreateCondBr(
2110 B.CreateICmpNE(
Sub, ConstantInt::get(CI->
getType(), 0)), BBNE,
2114 assert(
F &&
"Instruction does not belong to a function!");
2115 std::optional<uint64_t>
EC =
F->getEntryCount();
2122 Phi->addIncoming(
Sub, BBSubs[i]);
2130 Updates.
push_back({DominatorTree::Insert, BBCI, BBSubs[0]});
2133 Updates.
push_back({DominatorTree::Insert, BBSubs[i], BBSubs[i + 1]});
2134 Updates.
push_back({DominatorTree::Insert, BBSubs[i], BBNE});
2136 Updates.
push_back({DominatorTree::Insert, BBNE, BBTail});
2137 Updates.
push_back({DominatorTree::Delete, BBCI, BBTail});
2155 uint64_t Val = ConstInt->getZExtValue();
2177 Type *IndexTy =
DL.getIndexType(
Call->getType());
2181 Call->getContext(),
"memchr.success", BB->
getParent(), BBNext);
2192 ConstantInt::get(ByteTy,
static_cast<unsigned char>(Str[
I]));
2193 if (!Cases.
insert(CaseVal).second)
2198 SI->addCase(CaseVal, BBCase);
2200 IndexPHI->
addIncoming(ConstantInt::get(IndexTy,
I), BBCase);
2211 PHI->addIncoming(FirstOccursLocation, BBSuccess);
2213 Call->replaceAllUsesWith(
PHI);
2214 Call->eraseFromParent();
2225 bool &MadeCFGChange) {
2228 if (!CI || CI->isNoBuiltin())
2231 Function *CalledFunc = CI->getCalledFunction();
2246 case LibFunc_strcmp:
2247 case LibFunc_strncmp:
2248 if (StrNCmpInliner(CI, LF, &DTU,
DL).optimizeStrNCmp()) {
2249 MadeCFGChange =
true;
2253 case LibFunc_memchr:
2255 MadeCFGChange =
true;
2295 Type *Ty =
I.getType();
2296 if (!Ty->isIntOrIntVectorTy())
2299 unsigned BitWidth = Ty->getScalarSizeInBits();
2307 Value *XExt = Builder.CreateZExt(
X, NTy);
2308 Value *YExt = Builder.CreateZExt(
Y, NTy);
2309 Value *
Mul = Builder.CreateMul(XExt, YExt,
"",
true);
2311 Value *Res = Builder.CreateTrunc(
High, Ty,
"",
true);
2313 I.replaceAllUsesWith(Res);
2314 LLVM_DEBUG(
dbgs() <<
"Created long multiply from parts of " << *
X <<
" and "
2333 if (Carry->getOpcode() != Instruction::Select)
2337 Value *LowSum, *XhYl;
2347 if (!CheckHiLo(XhYl,
X,
Y)) {
2348 if (CheckHiLo(XhYl,
Y,
X))
2376 if (!CheckLoLo(XlYl,
X,
Y))
2378 if (!CheckHiLo(XlYh,
Y,
X))
2381 return CreateMulHigh(
X,
Y);
2389 Value *XlYh, *XhYl, *XlYl, *C2, *C3;
2429 if (!CheckHiLo(XlYh,
Y,
X))
2431 if (!CheckHiLo(XlYh,
Y,
X))
2433 if (!CheckHiLo(XhYl,
X,
Y))
2435 if (!CheckLoLo(XlYl,
X,
Y))
2438 return CreateMulHigh(
X,
Y);
2462 if (!CheckHiLo(XhYl,
X,
Y))
2496 if (!CheckLoLo(XlYl,
X,
Y))
2499 return CreateMulHigh(
X,
Y);
2507 if (Carry->getOpcode() != Instruction::Select)
2509 if (Carry->getOpcode() != Instruction::Select)
2513 Value *CrossSum, *XhYl;
2527 Value *XlYl, *LowAccum;
2535 if (!CheckLoLo(XlYl,
X,
Y))
2538 if (!CheckHiLo(XhYl,
X,
Y))
2540 if (!CheckHiLo(XhYl,
X,
Y))
2548 return CreateMulHigh(
X,
Y);
2561 A->hasOneUse() &&
B->hasOneUse())
2562 if (FoldMulHighCarry(
X,
Y,
A,
B) || FoldMulHighLadder(
X,
Y,
A,
B))
2580 A->hasOneUse() &&
B->hasOneUse() &&
C->hasOneUse())
2581 return FoldMulHighCarry4(
X,
Y,
A,
B,
C) ||
2582 FoldMulHighLadder4(
X,
Y,
A,
B,
C);
2593 bool &MadeCFGChange) {
2605 I, InstrProfValueKind::IPVK_MemOPSize, 2, TotalCount);
2606 std::optional<uint64_t> ZeroCount = std::nullopt;
2607 std::optional<uint64_t> OneCount = std::nullopt;
2608 for (
const auto [MemOpSize, SizeFrequency] : MemsetVPMetadata) {
2610 ZeroCount = SizeFrequency;
2611 else if (MemOpSize == 1)
2612 OneCount = SizeFrequency;
2615 if (MemsetVPMetadata.
size() == 1) {
2616 if (ZeroCount.has_value())
2618 else if (OneCount.has_value())
2622 BasicBlock *HeadBlock =
MI->getIterator()->getParent();
2625 Value *IsNonZero =
B.CreateIsNotNull(
MI->getLength(),
"memset.notzero");
2627 IsNonZero,
MI->getIterator(),
false,
2632 ZeroCount.has_value() && (*OneCount + *ZeroCount > 0))
2639 MI->getValue(),
MI->getDest(),
MI->getDestAlign(),
MI->isVolatile());
2640 Store->copyMetadata(*
MI, LLVMContext::MD_DIAssignID);
2641 MI->eraseFromParent();
2642 ++NumMemSetsGuarded;
2643 MadeCFGChange =
true;
2654 bool MadeChange =
false;
2707 bool MadeChange =
false;
2710 MadeChange |= TIC.
run(
F);
2722 bool MadeCFGChange =
false;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void replaceWithPopCount(Instruction &I, Value *Root)
Helper function to replace an instruction with a popcount intrinsic.
static bool tryToRecognizeTableBasedLog2(LoadInst *LI, Type *AccessType, GlobalVariable *GVTable, Value *GepIdx, const APInt &GEPScale, const DataLayout &DL, TargetTransformInfo &TTI)
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 isLog2Table(Constant *Table, const APInt &Mul, const APInt &Shift, Type *AccessTy, unsigned InputBits, const APInt &GEPIdxFactor, const DataLayout &DL)
static bool tryToRecognizeTableBasedLowBitsMask(LoadInst *LI, Type *AccessType, GlobalVariable *GVTable, Value *GepIdx, const APInt &GEPScale, const DataLayout &DL)
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 foldSelectSplitCTLZ(Instruction &I, Value *HiPart, Value *LoResult, Value *HiResult, Type *HalfTy)
Same as foldSelectSplitCTTZ but for leading zeros (ctlz).
static bool foldMemChr(CallInst *Call, DomTreeUpdater *DTU, const DataLayout &DL)
Convert memchr with a small constant string into a switch.
static Value * matchPopCountBytes(Value *V, unsigned Len, const DataLayout &DL)
static bool tryToRecognizePopCount2n3(Instruction &I)
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 tryToRecognizeTableBasedPatterns(Instruction &I, const DataLayout &DL, TargetTransformInfo &TTI)
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 mergePartStores(SmallVectorImpl< PartStore > &Parts, const DataLayout &DL, TargetTransformInfo &TTI)
static bool foldLoadsRecursive(Value *V, LoadOps &LOps, const DataLayout &DL, AliasAnalysis &AA, bool IsRoot=false)
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 tryToRecognizeTableBasedCttz(LoadInst *LI, Type *AccessType, GlobalVariable *GVTable, Value *GepIdx, const APInt &GEPScale, const DataLayout &DL)
static bool foldSelectSplitCTLZCTTZ(Instruction &I)
Common entry point for folding select-based split cttz/ctlz patterns.
static bool tryToRecognizePopCount1(Instruction &I)
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 foldSelectSplitCTTZ(Instruction &I, Value *LoTrunc, Value *HiResult, Value *LoResult, Type *HalfTy)
Try to fold a select-based split cttz pattern into a single full-width cttz.
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 tryToRecognizeTableBasedCtpop(LoadInst *LI, Type *AccessType, GlobalVariable *GVTable, Value *GepIdx, const APInt &GEPScale, const DataLayout &DL, const TargetTransformInfo &TTI)
static bool foldMemSetZeroOrOneLength(Instruction &I, const DataLayout &DL, TargetLibraryInfo &TLI, AssumptionCache &AC, DominatorTree &DT, bool &MadeCFGChange)
Guard a memset whose nonconstant length is known to be in [0, 1].
static bool foldLibCalls(Instruction &I, TargetTransformInfo &TTI, TargetLibraryInfo &TLI, AssumptionCache &AC, DominatorTree &DT, const DataLayout &DL, bool &MadeCFGChange)
static bool foldMulHigh(Instruction &I)
Match high part of long multiplication.
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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool runImpl(MachineFunction &MF)
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.
const SmallVectorImpl< MachineOperand > & Cond
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::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
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.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
unsigned getActiveBits() const
Compute the number of active bits in the value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
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.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
bool slt(const APInt &RHS) const
Signed less than comparison.
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
unsigned countTrailingOnes() const
bool isOne() const
Determine if this is a value of 1.
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.
LLVM_ABI 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.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
Get the first element.
size_t size() const
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; assumes that the block is well-formed.
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.
@ ICMP_ULT
unsigned less than
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...
bool equalsInt(uint64_t V) const
A helper method that can be used to determine if the constant contained within is equal to a constant...
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.
static LLVM_ABI DebugLoc getMergedLocations(ArrayRef< DebugLoc > Locs)
Try to combine the vector of locations passed as input in a single one.
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
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
bool hasDefinitiveInitializer() const
hasDefinitiveInitializer - Whether the global variable has an initializer, and any other instances of...
static bool isEquality(Predicate P)
Return true if this predicate is either EQ or NE.
void SetCurrentDebugLocation(const DebugLoc &L)
Set location information used by debugging information.
UncondBrInst * CreateBr(BasicBlock *Dest)
Create an unconditional 'br label X' instruction.
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)
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
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 const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
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()
static LocationSize precise(uint64_t Value)
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...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
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 reserve(size_type N)
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.
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.
LibFunc getLibFunc(StringRef funcName) 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 unsigned getIntegerBitWidth() const
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
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.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI bool hasNUsesOrMore(unsigned N) const
Return true if this value has N uses or more.
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 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.
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.
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, bool IsSigned=false)
Compute GCD of two APInt values.
@ 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)
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
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).
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
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)
match_bind< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
match_deferred< 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()...
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
auto m_SMax(const Opnd0 &Op0, const Opnd1 &Op1)
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
auto m_Value()
Match an arbitrary value and ignore it.
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)
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)
auto m_Ctlz(const Opnd0 &Op0, const Opnd1 &Op1)
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.
match_combine_or< BinaryOp_match< LHS, RHS, Instruction::Add >, DisjointOr_match< LHS, RHS > > m_AddLike(const LHS &L, const RHS &R)
Match either "add" or "or disjoint".
CastInst_match< OpTy, FPToSIInst > m_FPToSI(const OpTy &Op)
auto m_SMin(const Opnd0 &Op0, const Opnd1 &Op1)
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)
brc_match< Cond_t, match_bind< BasicBlock >, match_bind< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
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::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
auto m_Cttz(const Opnd0 &Op0, const Opnd1 &Op1)
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &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.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
LLVM_ABI cl::opt< bool > ProfcheckDisableMetadataFixes
LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I, StringRef PassName, const Function *F=nullptr)
Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch weights in the new instruct...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ Store
The extracted value is stored (ExtractElement only).
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 void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
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...
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
LLVM_ABI void setExplicitlyUnknownBranchWeights(Instruction &I, StringRef PassName)
Specify that the branch weights for this terminator cannot be known at compile time.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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)
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
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.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
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.
LLVM_ABI SmallVector< InstrProfValueData, 4 > getValueProfDataFromInst(const Instruction &Inst, InstrProfValueKind ValueKind, uint32_t MaxNumValueData, uint64_t &TotalC, bool GetNoICPValue=false)
Extract the value profile data from Inst and returns them if Inst is annotated with value profile dat...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
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.
LLVM_ABI bool isOnlyUsedInZeroComparison(const Instruction *CtxI)
@ Sub
Subtraction of integers.
LLVM_ABI BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the specified block at the specified instruction.
@ Fast
Assign the register banks as fast as possible (default).
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 Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
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.
@ End
Run the machine verifier once, at the end of the pipeline.
LLVM_ABI void setFittedBranchWeights(Instruction &I, ArrayRef< uint64_t > Weights, bool IsExpected, bool ElideAllZero=false)
Variant of setBranchWeights where the Weights will be fit first to uint32_t by shifting right.
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.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
A MapVector that performs no allocations if smaller than a certain size.