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");
57 "Number of select-based split cttz patterns folded");
59 "Number of select-based split ctlz patterns folded");
63 cl::desc(
"Max number of instructions to scan for aggressive instcombine."));
67 cl::desc(
"The maximum length of a constant string for a builtin string cmp "
68 "call eligible for inlining. The default value is 3."));
72 cl::desc(
"The maximum length of a constant string to "
73 "inline a memchr call."));
94 Type *HalfTy =
I.getType();
105 unsigned FullWidth = HalfWidth * 2;
110 Value *HiResult, *LoResult;
144 if (!
match(HiCttzArg,
150 Value *CttzWide = Builder.CreateIntrinsic(
151 Intrinsic::cttz, {SrcVal->
getType()}, {SrcVal, Builder.getFalse()});
152 Value *Trunc = Builder.CreateTrunc(CttzWide, HalfTy);
154 I.replaceAllUsesWith(Trunc);
155 ++NumSelectCTTZFolded;
179 Type *HalfTy =
I.getType();
190 unsigned FullWidth = HalfWidth * 2;
195 Value *LoResult, *HiResult;
227 if (!
match(HiCtlzArg,
246 Value *CtlzWide = Builder.CreateIntrinsic(
247 Intrinsic::ctlz, {SrcVal->
getType()}, {SrcVal, Builder.getFalse()});
248 Value *Trunc = Builder.CreateTrunc(CtlzWide, HalfTy);
250 I.replaceAllUsesWith(Trunc);
251 ++NumSelectCTLZFolded;
259 if (
I.getOpcode() != Instruction::PHI ||
I.getNumOperands() != 2)
273 unsigned Width = V->getType()->getScalarSizeInBits();
281 return Intrinsic::fshl;
290 return Intrinsic::fshr;
302 unsigned FunnelOp = 0, GuardOp = 1;
303 Value *P0 = Phi.getOperand(0), *P1 = Phi.getOperand(1);
304 Value *ShVal0, *ShVal1, *ShAmt;
307 (IID == Intrinsic::fshl && ShVal0 != P1) ||
308 (IID == Intrinsic::fshr && ShVal1 != P1)) {
311 (IID == Intrinsic::fshl && ShVal0 != P0) ||
312 (IID == Intrinsic::fshr && ShVal1 != P0))
314 assert((IID == Intrinsic::fshl || IID == Intrinsic::fshr) &&
315 "Pattern must match funnel shift left or right");
323 BasicBlock *GuardBB = Phi.getIncomingBlock(GuardOp);
324 BasicBlock *FunnelBB = Phi.getIncomingBlock(FunnelOp);
339 if (ShVal0 == ShVal1)
342 ++NumGuardedFunnelShifts;
346 bool IsFshl = IID == Intrinsic::fshl;
347 if (ShVal0 != ShVal1) {
349 ShVal1 = Builder.CreateFreeze(ShVal1);
351 ShVal0 = Builder.CreateFreeze(ShVal0);
368 Phi.replaceAllUsesWith(
369 Builder.CreateIntrinsic(IID, Phi.getType(), {ShVal0, ShVal1, ShAmt}));
379 Value *Root =
nullptr;
382 bool FoundAnd1 =
false;
384 MaskOps(
unsigned BitWidth,
bool MatchAnds)
385 : Mask(APInt::getZero(
BitWidth)), MatchAndChain(MatchAnds) {}
398 if (MOps.MatchAndChain) {
403 MOps.FoundAnd1 =
true;
417 const APInt *BitIndex =
nullptr;
423 MOps.Root = Candidate;
431 return MOps.Root == Candidate;
445 bool MatchAllBitsSet;
448 if (
I.getType()->isIntOrIntVectorTy(1)) {
450 MatchAllBitsSet =
true;
452 MatchAllBitsSet =
false;
460 MatchAllBitsSet =
true;
464 MatchAllBitsSet =
false;
469 Type *Ty =
X->getType();
471 MaskOps MOps(Ty->getScalarSizeInBits(), MatchAllBitsSet);
473 (MatchAllBitsSet && !MatchTrunc && !MOps.FoundAnd1))
479 Constant *Mask = ConstantInt::get(Ty, MOps.Mask);
480 Value *
And = Builder.CreateAnd(MOps.Root, Mask);
481 Value *Cmp = MatchAllBitsSet ? Builder.CreateICmpEQ(
And, Mask)
482 : Builder.CreateIsNotNull(
And);
483 Value *Zext = MatchTrunc ? Cmp : Builder.CreateZExt(Cmp, Ty);
484 I.replaceAllUsesWith(Zext);
485 ++NumAnyOrAllBitsSet;
495 Type *OrigTy =
I.getType();
498 Value *NewVal = Builder.CreateIntrinsic(Intrinsic::ctpop, RootTy, {Root});
499 if (OrigTy != RootTy) {
501 "Only truncation is supported for now");
502 NewVal = Builder.CreateTrunc(NewVal, OrigTy);
504 I.replaceAllUsesWith(NewVal);
505 ++NumPopCountRecognized;
520 if (
I.getOpcode() != Instruction::LShr)
523 Type *Ty =
I.getType();
524 if (!Ty->isIntOrIntVectorTy())
527 unsigned Len = Ty->getScalarSizeInBits();
529 if (!(Len <= 128 && Len > 8 && Len % 8 == 0))
538 Value *Op0 =
I.getOperand(0);
539 Value *Op1 =
I.getOperand(1);
555 Value *Root, *SubOp1;
557 const APInt *AndMask;
561 auto CheckAndMask = [&]() {
562 if (*AndMask == Mask55)
570 APInt NeededMask = Mask55 & ~*AndMask;
576 if (CheckAndMask()) {
611 if (
I.getOpcode() != Instruction::Add)
614 Type *Ty =
I.getType();
615 if (!Ty->isIntOrIntVectorTy())
618 unsigned Len = Ty->getScalarSizeInBits();
619 if (Len > 64 || Len <= 8 || Len % 8 != 0)
635 auto isValidNarrowedMask = [&](
const APInt &CapturedMask,
636 const APInt &ExpectedMask,
637 Value *Operand) ->
bool {
638 if (CapturedMask == ExpectedMask)
642 APInt NeededMask = ExpectedMask & ~CapturedMask;
648 auto narrowAddPairMasksOk = [&](
const APInt &BaseMask,
unsigned ShiftAmt,
650 const APInt &AndMask2) ->
bool {
651 if (!AndMask1.isSubsetOf(BaseMask) || !AndMask2.isSubsetOf(BaseMask))
653 APInt NeededShifted = (BaseMask & ~AndMask1).shl(ShiftAmt);
654 APInt NeededUnshifted = BaseMask & ~AndMask2;
655 APInt AllNeeded = NeededShifted | NeededUnshifted;
661 for (
unsigned I = Len;
I >= 8;
I =
I / 2) {
663 const APInt *AndMask1 =
nullptr, *AndMask2 =
nullptr;
671 if (!narrowAddPairMasksOk(Mask,
I / 2, ShiftOp, *AndMask1, *AndMask2))
676 else if (
match(Start,
679 if (!isValidNarrowedMask(*AndMask1, Mask, ShiftOp))
687 const APInt *AndMask1 =
nullptr, *AndMask2 =
nullptr;
692 if (!narrowAddPairMasksOk(Mask33, 2, ShiftOp, *AndMask1, *AndMask2))
704 if (!narrowAddPairMasksOk(Mask55, 1, Root, *AndMask1, *AndMask2))
732 if (
I.getOpcode() != Instruction::And)
735 Type *Ty =
I.getType();
736 if (!Ty->isIntOrIntVectorTy())
739 unsigned Len = Ty->getScalarSizeInBits();
741 const APInt *MaskRes;
755 if (Len > 64 || Len <= 8 || Len % 8 != 0)
767 unsigned NumLenBits =
Log2_32(Len) + 1;
778 for (
unsigned I = Len;
I >= 16;
I =
I / 2) {
829 const APInt *MinC, *MaxC;
839 if (!(*MinC + 1).isPowerOf2() || -*MaxC != *MinC + 1)
842 Type *IntTy =
I.getType();
843 Type *FpTy = In->getType();
854 SatCost +=
TTI.getCastInstrCost(Instruction::SExt, IntTy, SatTy,
861 MinMaxCost +=
TTI.getIntrinsicInstrCost(
864 MinMaxCost +=
TTI.getIntrinsicInstrCost(
868 if (SatCost >= MinMaxCost)
873 Builder.CreateIntrinsic(Intrinsic::fptosi_sat, {SatTy, FpTy}, In);
874 I.replaceAllUsesWith(Builder.CreateSExt(Sat, IntTy));
892 if (
TTI.haveFastSqrt(Ty) &&
893 (
Call->hasNoNaNs() ||
898 Builder.CreateIntrinsic(Intrinsic::sqrt, Ty, Arg,
Call,
"sqrt");
899 Call->replaceAllUsesWith(NewSqrt);
903 Call->eraseFromParent();
915 unsigned InputBits,
const APInt &GEPIdxFactor,
917 for (
unsigned Idx = 0; Idx < InputBits; Idx++) {
922 if (!
C ||
C->getValue() != Idx)
998 if (!
GEP || !
GEP->hasNoUnsignedSignedWrap())
1005 unsigned BW =
DL.getIndexTypeSizeInBits(
GEP->getType());
1006 APInt ModOffset(BW, 0);
1008 if (!
GEP->collectOffset(
DL, BW, VarOffsets, ModOffset) ||
1009 VarOffsets.
size() != 1 || ModOffset != 0)
1011 auto [GepIdx, GEPScale] = VarOffsets.
front();
1014 const APInt *MulConst, *ShiftConst, *AndCst =
nullptr;
1019 auto MatchInner =
m_LShr(
1027 if (InputBits != 16 && InputBits != 32 && InputBits != 64 && InputBits != 128)
1030 if (!GEPScale.isIntN(InputBits) ||
1033 InputBits, GEPScale.zextOrTrunc(InputBits),
DL))
1038 bool DefinedForZero = ZeroTableElem->
getZExtValue() == InputBits;
1043 auto Cttz =
B.CreateIntrinsic(Intrinsic::cttz, {XType}, {X1, BoolConst});
1044 Value *ZExtOrTrunc =
nullptr;
1046 if (DefinedForZero) {
1047 ZExtOrTrunc =
B.CreateZExtOrTrunc(Cttz, AccessType);
1051 auto Cmp =
B.CreateICmpEQ(X1, ConstantInt::get(XType, 0));
1052 auto Select =
B.CreateSelect(Cmp,
B.CreateZExt(ZeroTableElem, XType), Cttz);
1057 SelectI->setMetadata(
1058 LLVMContext::MD_prof,
1065 ZExtOrTrunc =
B.CreateZExtOrTrunc(
Select, AccessType);
1077 Type *AccessTy,
unsigned InputBits,
1079 for (
unsigned Idx = 0; Idx < InputBits; Idx++) {
1083 if (!
C ||
C->getValue() != Idx)
1167 if (!
GEP || !
GEP->hasNoUnsignedSignedWrap())
1174 unsigned BW =
DL.getIndexTypeSizeInBits(
GEP->getType());
1175 APInt ModOffset(BW, 0);
1177 if (!
GEP->collectOffset(
DL, BW, VarOffsets, ModOffset) ||
1178 VarOffsets.
size() != 1 || ModOffset != 0)
1180 auto [GepIdx, GEPScale] = VarOffsets.
front();
1183 const APInt *MulConst, *ShiftConst;
1190 unsigned InputBits =
X->getType()->getScalarSizeInBits();
1191 if (InputBits != 16 && InputBits != 32 && InputBits != 64 && InputBits != 128)
1196 if (*ShiftConst != InputBits -
Log2_32(InputBits))
1200 for (
unsigned ShiftAmt = InputBits / 2; ShiftAmt != 0; ShiftAmt /= 2) {
1208 if (!GEPScale.isIntN(InputBits) ||
1210 AccessType, InputBits, GEPScale.zextOrTrunc(InputBits),
DL))
1219 Type *XType =
X->getType();
1225 Intrinsic::ctlz, XType,
1232 Value *Ctlz =
B.CreateIntrinsic(Intrinsic::ctlz, {XType}, {
X, BoolConst});
1234 Constant *InputBitsM1 = ConstantInt::get(XType, InputBits - 1);
1235 Value *
Sub =
B.CreateSub(InputBitsM1, Ctlz);
1238 Value *Cmp =
B.CreateICmpEQ(
X, ConstantInt::get(XType, 0));
1239 Value *
Select =
B.CreateSelect(Cmp,
B.CreateZExt(ZeroTableElem, XType),
Sub);
1244 SelectI->setMetadata(
1245 LLVMContext::MD_prof,
1249 Value *ZExtOrTrunc =
B.CreateZExtOrTrunc(
Select, AccessType);
1281 if (!IsRoot && !V->hasOneUse())
1313 bool IsBigEndian =
DL.isBigEndian();
1317 APInt Offset1(
DL.getIndexTypeSizeInBits(Load1Ptr->
getType()), 0);
1323 APInt Offset2(
DL.getIndexTypeSizeInBits(Load2Ptr->
getType()), 0);
1331 if (Load1Ptr != Load2Ptr)
1335 if (!
DL.typeSizeEqualsStoreSize(LI1->
getType()) ||
1336 !
DL.typeSizeEqualsStoreSize(LI2->
getType()))
1342 if (!Start->comesBefore(End)) {
1357 unsigned NumScanned = 0;
1359 make_range(Start->getIterator(), End->getIterator())) {
1360 if (Inst.mayWriteToMemory() &&
isModSet(
AA.getModRefInfo(&Inst,
Loc)))
1369 if (Offset2.
slt(Offset1)) {
1393 uint64_t ShiftDiff = IsBigEndian ? LoadSize2 : LoadSize1;
1396 if ((ShAmt2 - ShAmt1) != ShiftDiff || (Offset2 - Offset1) != PrevSize)
1406 LOps.
LoadSize = LoadSize1 + LoadSize2;
1413 LOps.
Shift = ShAmt1;
1437 bool Allowed =
TTI.isTypeLegal(WiderType);
1441 unsigned AS = LI1->getPointerAddressSpace();
1443 Allowed =
TTI.allowsMisalignedMemoryAccesses(
I.getContext(), LOps.
LoadSize,
1444 AS, LI1->getAlign(), &
Fast);
1445 if (!Allowed || !
Fast)
1449 Value *Load1Ptr = LI1->getPointerOperand();
1452 APInt Offset1(
DL.getIndexTypeSizeInBits(Load1Ptr->
getType()), 0);
1455 Load1Ptr = Builder.CreatePtrAdd(Load1Ptr, Builder.getInt(Offset1));
1458 NewLoad = Builder.CreateAlignedLoad(WiderType, Load1Ptr, LI1->getAlign(),
1459 LI1->isVolatile(),
"");
1465 Value *NewOp = NewLoad;
1468 NewOp = Builder.CreateZExt(NewOp, LOps.
ZextType);
1473 NewOp = Builder.CreateShl(NewOp, LOps.
Shift);
1474 I.replaceAllUsesWith(NewOp);
1500 if (!Store || !Store->isSimple())
1501 return std::nullopt;
1503 Value *StoredVal = Store->getValueOperand();
1505 if (!StoredTy->
isIntegerTy() || !
DL.typeSizeEqualsStoreSize(StoredTy))
1506 return std::nullopt;
1512 return std::nullopt;
1514 Value *Ptr = Store->getPointerOperand();
1517 DL, PtrOffset,
true);
1518 return {{PtrBase, PtrOffset, Val, ValOffset, ValWidth, Store}};
1524 if (Parts.
size() < 2)
1533 if (!
TTI.isTypeLegal(NewTy) ||
1534 !
TTI.allowsMisalignedMemoryAccesses(Ctx, Width,
1535 First.Store->getPointerAddressSpace(),
1543 if (
First.ValOffset != 0)
1544 Val = Builder.CreateLShr(Val,
First.ValOffset);
1545 Val = Builder.CreateZExtOrTrunc(Val, NewTy);
1546 StoreInst *Store = Builder.CreateAlignedStore(
1547 Val,
First.Store->getPointerOperand(),
First.Store->getAlign());
1556 AATags = AATags.
concat(Part.Store->getAAMetadata());
1558 DbgLocs.
push_back(Part.Store->getDebugLoc());
1560 Store->setAAMetadata(AATags);
1561 Store->mergeDIAssignID(Stores);
1566 Part.Store->eraseFromParent();
1573 if (Parts.
size() < 2)
1582 int64_t LastEndOffsetFromFirst = 0;
1585 APInt PtrOffsetFromFirst = Part.PtrOffset -
First->PtrOffset;
1586 int64_t ValOffsetFromFirst = Part.ValOffset -
First->ValOffset;
1587 if (PtrOffsetFromFirst * 8 != ValOffsetFromFirst ||
1588 LastEndOffsetFromFirst != ValOffsetFromFirst) {
1590 LastEndOffsetFromFirst,
DL,
TTI);
1592 LastEndOffsetFromFirst = Part.ValWidth;
1596 LastEndOffsetFromFirst = ValOffsetFromFirst + Part.ValWidth;
1600 LastEndOffsetFromFirst,
DL,
TTI);
1607 if (
DL.isBigEndian())
1612 bool MadeChange =
false;
1615 if (Parts.
empty() || Part->isCompatibleWith(Parts[0])) {
1630 (
I.mayReadOrWriteMemory() &&
1647 if (!
I ||
I->getOpcode() != Instruction::Or || !
I->hasOneUse())
1654 Value *Op0 =
I->getOperand(0);
1661 Value *Op1 =
I->getOperand(1);
1668 if (Op0 !=
I->getOperand(0) || Op1 !=
I->getOperand(1))
1669 return Builder.CreateOr(Op0, Op1);
1685 if (OpI->getOpcode() == Instruction::Or)
1692 I.replaceAllUsesWith(Builder.CreateICmp(Pred, Res,
I.getOperand(1)));
1701static std::pair<APInt, APInt>
1703 unsigned BW =
DL.getIndexTypeSizeInBits(PtrOp->
getType());
1704 std::optional<APInt> Stride;
1705 APInt ModOffset(BW, 0);
1710 if (!
GEP->collectOffset(
DL, BW, VarOffsets, ModOffset))
1713 for (
auto [V, Scale] : VarOffsets) {
1715 if (!
GEP->hasNoUnsignedSignedWrap())
1724 PtrOp =
GEP->getPointerOperand();
1734 ModOffset = ModOffset.
srem(*Stride);
1736 ModOffset += *Stride;
1738 return {*Stride, ModOffset};
1745 if (!LI || LI->isVolatile())
1750 auto *PtrOp = LI->getPointerOperand();
1752 if (!GV || !GV->isConstant() || !GV->hasDefinitiveInitializer())
1757 uint64_t GVSize =
DL.getTypeAllocSize(
C->getType());
1758 if (!GVSize || 4096 < GVSize)
1761 Type *LoadTy = LI->getType();
1762 unsigned BW =
DL.getIndexTypeSizeInBits(PtrOp->getType());
1768 if (
auto LA = LI->getAlign();
1769 LA <= GV->
getAlign().valueOrOne() && Stride.getZExtValue() < LA.value()) {
1770 ConstOffset =
APInt(BW, 0);
1771 Stride =
APInt(BW, LA.value());
1778 unsigned E = GVSize -
DL.getTypeStoreSize(LoadTy);
1779 for (; ConstOffset.getZExtValue() <=
E; ConstOffset += Stride)
1783 I.replaceAllUsesWith(Ca);
1789class StrNCmpInliner {
1791 StrNCmpInliner(CallInst *CI, LibFunc Func, DomTreeUpdater *DTU,
1792 const DataLayout &DL)
1793 : CI(CI), Func(Func), DTU(DTU), DL(DL) {}
1795 bool optimizeStrNCmp();
1798 void inlineCompare(
Value *
LHS, StringRef
RHS, uint64_t
N,
bool Swapped);
1802 DomTreeUpdater *DTU;
1803 const DataLayout &DL;
1836bool StrNCmpInliner::optimizeStrNCmp() {
1849 StringRef Str1, Str2;
1852 if (HasStr1 == HasStr2)
1856 StringRef Str = HasStr1 ? Str1 : Str2;
1857 Value *StrP = HasStr1 ? Str2P : Str1P;
1859 size_t Idx = Str.find(
'\0');
1861 if (Func == LibFunc_strncmp) {
1863 N = std::min(
N, ConstInt->getZExtValue());
1873 bool CanBeNull =
false, CanBeFreed =
false;
1876 inlineCompare(StrP, Str,
N, HasStr1);
1914void StrNCmpInliner::inlineCompare(
Value *
LHS, StringRef
RHS, uint64_t
N,
1931 for (uint64_t
I = 0;
I <
N; ++
I)
1938 B.SetInsertPoint(BBNE);
1943 for (uint64_t i = 0; i <
N; ++i) {
1944 B.SetInsertPoint(BBSubs[i]);
1946 B.CreateZExt(
B.CreateLoad(
B.getInt8Ty(),
1947 B.CreateInBoundsPtrAdd(
Base,
B.getInt64(i))),
1950 ConstantInt::get(CI->
getType(),
static_cast<unsigned char>(
RHS[i]));
1951 Value *
Sub = Swapped ?
B.CreateSub(VR, VL) :
B.CreateSub(VL, VR);
1953 CondBrInst *CondBrInst =
B.CreateCondBr(
1954 B.CreateICmpNE(
Sub, ConstantInt::get(CI->
getType(), 0)), BBNE,
1958 assert(
F &&
"Instruction does not belong to a function!");
1959 std::optional<Function::ProfileCount>
EC =
F->getEntryCount();
1960 if (EC &&
EC->getCount() > 0)
1966 Phi->addIncoming(
Sub, BBSubs[i]);
1974 Updates.
push_back({DominatorTree::Insert, BBCI, BBSubs[0]});
1975 for (uint64_t i = 0; i <
N; ++i) {
1977 Updates.
push_back({DominatorTree::Insert, BBSubs[i], BBSubs[i + 1]});
1978 Updates.
push_back({DominatorTree::Insert, BBSubs[i], BBNE});
1980 Updates.
push_back({DominatorTree::Insert, BBNE, BBTail});
1981 Updates.
push_back({DominatorTree::Delete, BBCI, BBTail});
1999 uint64_t Val = ConstInt->getZExtValue();
2021 Type *IndexTy =
DL.getIndexType(
Call->getType());
2025 Call->getContext(),
"memchr.success", BB->
getParent(), BBNext);
2036 ConstantInt::get(ByteTy,
static_cast<unsigned char>(Str[
I]));
2037 if (!Cases.
insert(CaseVal).second)
2042 SI->addCase(CaseVal, BBCase);
2044 IndexPHI->
addIncoming(ConstantInt::get(IndexTy,
I), BBCase);
2055 PHI->addIncoming(FirstOccursLocation, BBSuccess);
2057 Call->replaceAllUsesWith(
PHI);
2058 Call->eraseFromParent();
2069 bool &MadeCFGChange) {
2072 if (!CI || CI->isNoBuiltin())
2075 Function *CalledFunc = CI->getCalledFunction();
2091 case LibFunc_strcmp:
2092 case LibFunc_strncmp:
2093 if (StrNCmpInliner(CI, LF, &DTU,
DL).optimizeStrNCmp()) {
2094 MadeCFGChange =
true;
2098 case LibFunc_memchr:
2100 MadeCFGChange =
true;
2140 Type *Ty =
I.getType();
2141 if (!Ty->isIntOrIntVectorTy())
2144 unsigned BitWidth = Ty->getScalarSizeInBits();
2152 Value *XExt = Builder.CreateZExt(
X, NTy);
2153 Value *YExt = Builder.CreateZExt(
Y, NTy);
2154 Value *
Mul = Builder.CreateMul(XExt, YExt,
"",
true);
2156 Value *Res = Builder.CreateTrunc(
High, Ty,
"",
true);
2158 I.replaceAllUsesWith(Res);
2159 LLVM_DEBUG(
dbgs() <<
"Created long multiply from parts of " << *
X <<
" and "
2178 if (Carry->getOpcode() != Instruction::Select)
2182 Value *LowSum, *XhYl;
2192 if (!CheckHiLo(XhYl,
X,
Y)) {
2193 if (CheckHiLo(XhYl,
Y,
X))
2221 if (!CheckLoLo(XlYl,
X,
Y))
2223 if (!CheckHiLo(XlYh,
Y,
X))
2226 return CreateMulHigh(
X,
Y);
2234 Value *XlYh, *XhYl, *XlYl, *C2, *C3;
2274 if (!CheckHiLo(XlYh,
Y,
X))
2276 if (!CheckHiLo(XlYh,
Y,
X))
2278 if (!CheckHiLo(XhYl,
X,
Y))
2280 if (!CheckLoLo(XlYl,
X,
Y))
2283 return CreateMulHigh(
X,
Y);
2307 if (!CheckHiLo(XhYl,
X,
Y))
2341 if (!CheckLoLo(XlYl,
X,
Y))
2344 return CreateMulHigh(
X,
Y);
2352 if (Carry->getOpcode() != Instruction::Select)
2354 if (Carry->getOpcode() != Instruction::Select)
2358 Value *CrossSum, *XhYl;
2372 Value *XlYl, *LowAccum;
2380 if (!CheckLoLo(XlYl,
X,
Y))
2383 if (!CheckHiLo(XhYl,
X,
Y))
2385 if (!CheckHiLo(XhYl,
X,
Y))
2393 return CreateMulHigh(
X,
Y);
2406 A->hasOneUse() &&
B->hasOneUse())
2407 if (FoldMulHighCarry(
X,
Y,
A,
B) || FoldMulHighLadder(
X,
Y,
A,
B))
2425 A->hasOneUse() &&
B->hasOneUse() &&
C->hasOneUse())
2426 return FoldMulHighCarry4(
X,
Y,
A,
B,
C) ||
2427 FoldMulHighLadder4(
X,
Y,
A,
B,
C);
2439 bool MadeChange =
false;
2490 bool MadeChange =
false;
2493 MadeChange |= TIC.
run(
F);
2505 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 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 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 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 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 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 foldSelectSplitCTTZ(Instruction &I)
Try to fold a select-based split cttz pattern into a single full-width cttz.
static bool foldSelectSplitCTLZ(Instruction &I)
Same as foldSelectSplitCTTZ but for leading zeros (ctlz).
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 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 tryToRecognizeTableBasedLog2(Instruction &I, const DataLayout &DL, TargetTransformInfo &TTI)
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< 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, const LibcallLoweringInfo &Libcalls, 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.
const SmallVectorImpl< MachineOperand > & Cond
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::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.
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.
unsigned countTrailingOnes() const
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.
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...
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
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(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.
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()
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.
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 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 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)
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.
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.
MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > m_SMin(const LHS &L, const RHS &R)
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)
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)
MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty > m_SMax(const LHS &L, const RHS &R)
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)
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_Cttz(const Opnd0 &Op0, const Opnd1 &Op1)
brc_match< Cond_t, match_bind< BasicBlock >, match_bind< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_Ctlz(const Opnd0 &Op0, const Opnd1 &Op1)
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.
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.
FunctionAddr VTableAddr Value
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.
LLVM_ABI bool isOnlyUsedInZeroComparison(const Instruction *CxtI)
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)
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.
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.
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.
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.
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.