34using namespace PatternMatch;
36#define DEBUG_TYPE "instcombine"
45 const APInt &In2,
bool IsSigned =
false) {
48 Result = In1.
sadd_ov(In2, Overflow);
50 Result = In1.
uadd_ov(In2, Overflow);
58 const APInt &In2,
bool IsSigned =
false) {
61 Result = In1.
ssub_ov(In2, Overflow);
63 Result = In1.
usub_ov(In2, Overflow);
71 for (
auto *U :
I.users())
72 if (isa<BranchInst>(U))
82 if (!ICmpInst::isSigned(Pred))
89 if (Pred == ICmpInst::ICMP_SLT) {
90 Pred = ICmpInst::ICMP_SLE;
93 }
else if (
C.isAllOnes()) {
94 if (Pred == ICmpInst::ICMP_SGT) {
95 Pred = ICmpInst::ICMP_SGE;
114 if (
LI->isVolatile() ||
LI->getType() !=
GEP->getResultElementType() ||
120 if (!isa<ConstantArray>(
Init) && !isa<ConstantDataArray>(
Init))
123 uint64_t ArrayElementCount =
Init->getType()->getArrayNumElements();
132 if (
GEP->getNumOperands() < 3 || !isa<ConstantInt>(
GEP->getOperand(1)) ||
133 !cast<ConstantInt>(
GEP->getOperand(1))->isZero() ||
134 isa<Constant>(
GEP->getOperand(2)))
142 Type *EltTy =
Init->getType()->getArrayElementType();
143 for (
unsigned i = 3, e =
GEP->getNumOperands(); i != e; ++i) {
149 if ((
unsigned)IdxVal != IdxVal)
152 if (
StructType *STy = dyn_cast<StructType>(EltTy))
153 EltTy = STy->getElementType(IdxVal);
154 else if (
ArrayType *ATy = dyn_cast<ArrayType>(EltTy)) {
155 if (IdxVal >= ATy->getNumElements())
157 EltTy = ATy->getElementType();
165 enum { Overdefined = -3, Undefined = -2 };
174 int FirstTrueElement = Undefined, SecondTrueElement = Undefined;
178 int FirstFalseElement = Undefined, SecondFalseElement = Undefined;
186 int TrueRangeEnd = Undefined, FalseRangeEnd = Undefined;
195 for (
unsigned i = 0, e = ArrayElementCount; i != e; ++i) {
201 if (!LaterIndices.
empty()) {
216 CompareRHS,
DL, &
TLI);
221 if (isa<UndefValue>(
C)) {
224 if (TrueRangeEnd == (
int)i - 1)
226 if (FalseRangeEnd == (
int)i - 1)
233 if (!isa<ConstantInt>(
C))
238 bool IsTrueForElt = !cast<ConstantInt>(
C)->isZero();
243 if (FirstTrueElement == Undefined)
244 FirstTrueElement = TrueRangeEnd = i;
247 if (SecondTrueElement == Undefined)
248 SecondTrueElement = i;
250 SecondTrueElement = Overdefined;
253 if (TrueRangeEnd == (
int)i - 1)
256 TrueRangeEnd = Overdefined;
260 if (FirstFalseElement == Undefined)
261 FirstFalseElement = FalseRangeEnd = i;
264 if (SecondFalseElement == Undefined)
265 SecondFalseElement = i;
267 SecondFalseElement = Overdefined;
270 if (FalseRangeEnd == (
int)i - 1)
273 FalseRangeEnd = Overdefined;
278 if (i < 64 && IsTrueForElt)
279 MagicBitvector |= 1ULL << i;
284 if ((i & 8) == 0 && i >= 64 && SecondTrueElement == Overdefined &&
285 SecondFalseElement == Overdefined && TrueRangeEnd == Overdefined &&
286 FalseRangeEnd == Overdefined)
297 if (!
GEP->isInBounds()) {
300 if (
Idx->getType()->getPrimitiveSizeInBits().getFixedValue() > OffsetSize)
311 unsigned ElementSize =
324 if (SecondTrueElement != Overdefined) {
327 if (FirstTrueElement == Undefined)
330 Value *FirstTrueIdx = ConstantInt::get(
Idx->getType(), FirstTrueElement);
333 if (SecondTrueElement == Undefined)
338 Value *SecondTrueIdx = ConstantInt::get(
Idx->getType(), SecondTrueElement);
340 return BinaryOperator::CreateOr(C1, C2);
345 if (SecondFalseElement != Overdefined) {
348 if (FirstFalseElement == Undefined)
351 Value *FirstFalseIdx = ConstantInt::get(
Idx->getType(), FirstFalseElement);
354 if (SecondFalseElement == Undefined)
359 Value *SecondFalseIdx =
360 ConstantInt::get(
Idx->getType(), SecondFalseElement);
362 return BinaryOperator::CreateAnd(C1, C2);
367 if (TrueRangeEnd != Overdefined) {
368 assert(TrueRangeEnd != FirstTrueElement &&
"Should emit single compare");
372 if (FirstTrueElement) {
373 Value *Offs = ConstantInt::get(
Idx->getType(), -FirstTrueElement);
378 ConstantInt::get(
Idx->getType(), TrueRangeEnd - FirstTrueElement + 1);
383 if (FalseRangeEnd != Overdefined) {
384 assert(FalseRangeEnd != FirstFalseElement &&
"Should emit single compare");
387 if (FirstFalseElement) {
388 Value *Offs = ConstantInt::get(
Idx->getType(), -FirstFalseElement);
393 ConstantInt::get(
Idx->getType(), FalseRangeEnd - FirstFalseElement);
406 if (ArrayElementCount <= Idx->
getType()->getIntegerBitWidth())
440 while (!WorkList.
empty()) {
443 while (!WorkList.
empty()) {
444 if (Explored.
size() >= 100)
454 if (!isa<GetElementPtrInst>(V) && !isa<PHINode>(V))
459 if (
auto *
GEP = dyn_cast<GEPOperator>(V)) {
461 auto IsNonConst = [](
Value *V) {
return !isa<ConstantInt>(V); };
462 if (!
GEP->isInBounds() ||
count_if(
GEP->indices(), IsNonConst) > 1)
469 if (WorkList.
back() == V) {
475 if (
auto *PN = dyn_cast<PHINode>(V)) {
477 if (isa<CatchSwitchInst>(PN->getParent()->getTerminator()))
485 for (
auto *PN : PHIs)
486 for (
Value *
Op : PN->incoming_values())
494 for (
Value *Val : Explored) {
497 auto *
PHI = dyn_cast<PHINode>(
Use);
498 auto *Inst = dyn_cast<Instruction>(Val);
500 if (Inst ==
Base || Inst ==
PHI || !Inst || !
PHI ||
504 if (
PHI->getParent() == Inst->getParent())
515 if (
auto *
PHI = dyn_cast<PHINode>(V)) {
520 if (
auto *
I = dyn_cast<Instruction>(V)) {
522 I = &*std::next(
I->getIterator());
526 if (
auto *
A = dyn_cast<Argument>(V)) {
528 BasicBlock &Entry =
A->getParent()->getEntryBlock();
534 assert(isa<Constant>(V) &&
"Setting insertion point for unknown value!");
551 Base->getContext(),
DL.getIndexTypeSizeInBits(Start->getType()));
557 for (
Value *Val : Explored) {
562 if (
auto *
PHI = dyn_cast<PHINode>(Val))
565 PHI->getName() +
".idx",
PHI->getIterator());
570 for (
Value *Val : Explored) {
574 if (
auto *
GEP = dyn_cast<GEPOperator>(Val)) {
578 if (isa<ConstantInt>(
Op) && cast<ConstantInt>(
Op)->
isZero())
579 NewInsts[
GEP] = OffsetV;
582 Op, OffsetV,
GEP->getOperand(0)->getName() +
".add");
585 if (isa<PHINode>(Val))
592 for (
Value *Val : Explored) {
597 if (
auto *
PHI = dyn_cast<PHINode>(Val)) {
599 for (
unsigned I = 0, E =
PHI->getNumIncomingValues();
I < E; ++
I) {
600 Value *NewIncoming =
PHI->getIncomingValue(
I);
603 NewIncoming = NewInsts[NewIncoming];
610 for (
Value *Val : Explored) {
617 Builder.
getInt8Ty(),
Base, NewInsts[Val], Val->getName() +
".ptr");
624 return NewInsts[Start];
687 if (!isa<GetElementPtrInst>(
RHS))
699 isa<Constant>(
RHS) && cast<Constant>(
RHS)->isNullValue() &&
721 auto EC = cast<VectorType>(GEPLHS->
getType())->getElementCount();
726 cast<Constant>(
RHS),
Base->getType()));
730 if (PtrBase != GEPRHS->getOperand(0)) {
731 bool IndicesTheSame =
734 GEPRHS->getPointerOperand()->getType() &&
738 if (GEPLHS->
getOperand(i) != GEPRHS->getOperand(i)) {
739 IndicesTheSame =
false;
752 if (GEPLHS->
isInBounds() && GEPRHS->isInBounds() &&
754 (GEPRHS->hasAllConstantIndices() || GEPRHS->hasOneUse()) &&
758 Value *LOffset = EmitGEPOffset(GEPLHS);
759 Value *ROffset = EmitGEPOffset(GEPRHS);
766 if (LHSIndexTy != RHSIndexTy) {
785 bool GEPsInBounds = GEPLHS->
isInBounds() && GEPRHS->isInBounds();
789 unsigned NumDifferences = 0;
790 unsigned DiffOperand = 0;
791 for (
unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i)
792 if (GEPLHS->
getOperand(i) != GEPRHS->getOperand(i)) {
794 Type *RHSType = GEPRHS->getOperand(i)->getType();
805 if (NumDifferences++)
break;
809 if (NumDifferences == 0)
813 else if (NumDifferences == 1 && GEPsInBounds) {
815 Value *RHSV = GEPRHS->getOperand(DiffOperand);
823 Value *L = EmitGEPOffset(GEPLHS,
true);
824 Value *R = EmitGEPOffset(GEPRHS,
true);
851 bool Captured =
false;
856 CmpCaptureTracker(
AllocaInst *Alloca) : Alloca(Alloca) {}
858 void tooManyUses()
override { Captured =
true; }
860 bool captured(
const Use *U)
override {
861 auto *ICmp = dyn_cast<ICmpInst>(U->getUser());
869 auto Res = ICmps.
insert({ICmp, 0});
870 Res.first->second |= 1u << U->getOperandNo();
879 CmpCaptureTracker Tracker(Alloca);
881 if (Tracker.Captured)
884 bool Changed =
false;
885 for (
auto [ICmp,
Operands] : Tracker.ICmps) {
891 auto *Res = ConstantInt::get(
917 assert(!!
C &&
"C should not be zero!");
923 Constant *R = ConstantInt::get(
X->getType(),
933 ConstantInt::get(
X->getType(), -
C));
945 ConstantInt::get(
X->getType(),
SMax -
C));
956 ConstantInt::get(
X->getType(),
SMax - (
C - 1)));
965 assert(
I.isEquality() &&
"Cannot fold icmp gt/lt");
968 if (
I.getPredicate() ==
I.ICMP_NE)
977 bool IsAShr = isa<AShrOperator>(
I.getOperand(0));
989 return getICmp(
I.ICMP_UGT,
A,
990 ConstantInt::get(
A->getType(), AP2.
logBase2()));
1002 if (IsAShr && AP1 == AP2.
ashr(Shift)) {
1006 return getICmp(
I.ICMP_UGE,
A, ConstantInt::get(
A->getType(), Shift));
1007 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1008 }
else if (AP1 == AP2.
lshr(Shift)) {
1009 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1015 auto *TorF = ConstantInt::get(
I.getType(),
I.getPredicate() ==
I.ICMP_NE);
1024 assert(
I.isEquality() &&
"Cannot fold icmp gt/lt");
1027 if (
I.getPredicate() ==
I.ICMP_NE)
1038 if (!AP1 && AP2TrailingZeros != 0)
1041 ConstantInt::get(
A->getType(), AP2.
getBitWidth() - AP2TrailingZeros));
1049 if (Shift > 0 && AP2.
shl(Shift) == AP1)
1050 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1054 auto *TorF = ConstantInt::get(
I.getType(),
I.getPredicate() ==
I.ICMP_NE);
1075 Instruction *AddWithCst = cast<Instruction>(
I.getOperand(0));
1083 if (NewWidth != 7 && NewWidth != 15 && NewWidth != 31)
1107 if (U == AddWithCst)
1125 I.getModule(), Intrinsic::sadd_with_overflow, NewType);
1154 if (!
I.isEquality())
1185 APInt(XBitWidth, XBitWidth - 1))))
1187 }
else if (isa<BinaryOperator>(Val) &&
1212 return new ICmpInst(Pred,
B, Cmp.getOperand(1));
1214 return new ICmpInst(Pred,
A, Cmp.getOperand(1));
1231 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1243 return new ICmpInst(Pred,
Y, Cmp.getOperand(1));
1249 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1251 auto *BO0 = cast<OverflowingBinaryOperator>(Cmp.getOperand(0));
1252 if (BO0->hasNoUnsignedWrap() || BO0->hasNoSignedWrap()) {
1260 return new ICmpInst(Pred,
Y, Cmp.getOperand(1));
1265 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1297 Value *Op0 = Cmp.getOperand(0), *Op1 = Cmp.getOperand(1);
1310 if (
auto *Phi = dyn_cast<PHINode>(Op0))
1311 if (
all_of(Phi->operands(), [](
Value *V) { return isa<Constant>(V); })) {
1313 for (
Value *V : Phi->incoming_values()) {
1322 for (
auto [V, Pred] :
zip(Ops, Phi->blocks()))
1337 Value *
X = Cmp.getOperand(0), *
Y = Cmp.getOperand(1);
1370 if (Cmp.isEquality() || (IsSignBit &&
hasBranchUse(Cmp)))
1375 if (Cmp.hasOneUse() &&
1389 if (!
match(BI->getCondition(),
1395 if (
auto *V = handleDomCond(DomPred, DomC))
1415 Type *SrcTy =
X->getType();
1421 if (shouldChangeType(Trunc->
getType(), SrcTy)) {
1423 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy,
C.sext(SrcBits)));
1425 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy,
C.zext(SrcBits)));
1428 if (
C.isOne() &&
C.getBitWidth() > 1) {
1433 ConstantInt::get(V->getType(), 1));
1443 auto NewPred = (Pred == Cmp.ICMP_EQ) ? Cmp.ICMP_UGE : Cmp.ICMP_ULT;
1444 return new ICmpInst(NewPred,
Y, ConstantInt::get(SrcTy, DstBits));
1449 return new ICmpInst(Pred,
Y, ConstantInt::get(SrcTy,
C.logBase2()));
1452 if (Cmp.isEquality() && Trunc->
hasOneUse()) {
1455 if (!SrcTy->
isVectorTy() && shouldChangeType(DstBits, SrcBits)) {
1459 Constant *WideC = ConstantInt::get(SrcTy,
C.zext(SrcBits));
1468 if ((Known.
Zero | Known.
One).countl_one() >= SrcBits - DstBits) {
1470 APInt NewRHS =
C.zext(SrcBits);
1472 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy, NewRHS));
1480 const APInt *ShAmtC;
1501 bool YIsSExt =
false;
1504 unsigned NoWrapFlags = cast<TruncInst>(Cmp.getOperand(0))->getNoWrapKind() &
1505 cast<TruncInst>(Cmp.getOperand(1))->getNoWrapKind();
1506 if (Cmp.isSigned()) {
1517 if (
X->getType() !=
Y->getType() &&
1518 (!Cmp.getOperand(0)->hasOneUse() || !Cmp.getOperand(1)->hasOneUse()))
1520 if (!isDesirableIntType(
X->getType()->getScalarSizeInBits()) &&
1521 isDesirableIntType(
Y->getType()->getScalarSizeInBits())) {
1523 Pred = Cmp.getSwappedPredicate(Pred);
1528 else if (!Cmp.isSigned() &&
1538 isa<SExtInst>(Cmp.getOperand(0)) || isa<SExtInst>(Cmp.getOperand(1));
1542 Type *TruncTy = Cmp.getOperand(0)->getType();
1547 if (isDesirableIntType(TruncBits) &&
1548 !isDesirableIntType(
X->getType()->getScalarSizeInBits()))
1571 bool TrueIfSigned =
false;
1588 if (
Xor->hasOneUse()) {
1590 if (!Cmp.isEquality() && XorC->
isSignMask()) {
1591 Pred = Cmp.getFlippedSignednessPredicate();
1592 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(),
C ^ *XorC));
1597 Pred = Cmp.getFlippedSignednessPredicate();
1598 Pred = Cmp.getSwappedPredicate(Pred);
1599 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(),
C ^ *XorC));
1606 if (*XorC == ~
C && (
C + 1).isPowerOf2())
1609 if (*XorC ==
C && (
C + 1).isPowerOf2())
1614 if (*XorC == -
C &&
C.isPowerOf2())
1616 ConstantInt::get(
X->getType(), ~
C));
1618 if (*XorC ==
C && (-
C).isPowerOf2())
1620 ConstantInt::get(
X->getType(), ~
C));
1642 const APInt *ShiftC;
1647 Type *XType =
X->getType();
1653 return new ICmpInst(Pred,
Add, ConstantInt::get(XType, Bound));
1662 if (!Shift || !Shift->
isShift())
1670 unsigned ShiftOpcode = Shift->
getOpcode();
1671 bool IsShl = ShiftOpcode == Instruction::Shl;
1674 APInt NewAndCst, NewCmpCst;
1675 bool AnyCmpCstBitsShiftedOut;
1676 if (ShiftOpcode == Instruction::Shl) {
1684 NewCmpCst = C1.
lshr(*C3);
1685 NewAndCst = C2.
lshr(*C3);
1686 AnyCmpCstBitsShiftedOut = NewCmpCst.
shl(*C3) != C1;
1687 }
else if (ShiftOpcode == Instruction::LShr) {
1692 NewCmpCst = C1.
shl(*C3);
1693 NewAndCst = C2.
shl(*C3);
1694 AnyCmpCstBitsShiftedOut = NewCmpCst.
lshr(*C3) != C1;
1700 assert(ShiftOpcode == Instruction::AShr &&
"Unknown shift opcode");
1701 NewCmpCst = C1.
shl(*C3);
1702 NewAndCst = C2.
shl(*C3);
1703 AnyCmpCstBitsShiftedOut = NewCmpCst.
ashr(*C3) != C1;
1704 if (NewAndCst.
ashr(*C3) != C2)
1708 if (AnyCmpCstBitsShiftedOut) {
1718 Shift->
getOperand(0), ConstantInt::get(
And->getType(), NewAndCst));
1719 return new ICmpInst(Cmp.getPredicate(),
1720 NewAnd, ConstantInt::get(
And->getType(), NewCmpCst));
1752 if (isICMP_NE && Cmp.getType()->isVectorTy() && C1.
isZero() &&
1754 return new TruncInst(
And->getOperand(0), Cmp.getType());
1762 if (!
And->hasOneUse())
1765 if (Cmp.isEquality() && C1.
isZero()) {
1783 Constant *NegBOC = ConstantInt::get(
And->getType(), -NewC2);
1785 return new ICmpInst(NewPred,
X, NegBOC);
1803 if (!Cmp.getType()->isVectorTy()) {
1804 Type *WideType = W->getType();
1806 Constant *ZextC1 = ConstantInt::get(WideType, C1.
zext(WideScalarBits));
1807 Constant *ZextC2 = ConstantInt::get(WideType, C2->
zext(WideScalarBits));
1809 return new ICmpInst(Cmp.getPredicate(), NewAnd, ZextC1);
1820 if (!Cmp.isSigned() && C1.
isZero() &&
And->getOperand(0)->hasOneUse() &&
1822 Constant *One = cast<Constant>(
And->getOperand(1));
1827 unsigned UsesRemoved = 0;
1828 if (
And->hasOneUse())
1830 if (
Or->hasOneUse())
1837 if (UsesRemoved >= RequireUsesRemoved) {
1841 One,
Or->getName());
1853 if (!Cmp.getParent()->getParent()->hasFnAttribute(
1854 Attribute::NoImplicitFloat) &&
1857 Type *FPType = V->getType()->getScalarType();
1859 APInt ExponentMask =
1861 if (C1 == ExponentMask) {
1894 Constant *MinSignedC = ConstantInt::get(
1898 return new ICmpInst(NewPred,
X, MinSignedC);
1907 if (
auto *C2 = dyn_cast<ConstantInt>(
Y))
1908 if (
auto *
LI = dyn_cast<LoadInst>(
X))
1909 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(
LI->getOperand(0)))
1910 if (
auto *GV = dyn_cast<GlobalVariable>(
GEP->getOperand(0)))
1915 if (!Cmp.isEquality())
1921 if (Cmp.getOperand(1) ==
Y &&
C.isNegatedPowerOf2()) {
1924 return new ICmpInst(NewPred,
X,
SubOne(cast<Constant>(Cmp.getOperand(1))));
1937 assert(Cmp.isEquality() &&
"Not expecting non-equality predicates");
1939 const APInt *TC, *FC;
1956 X->getType()->isIntOrIntVectorTy(1) && (
C.isZero() ||
C.isOne())) {
1962 return BinaryOperator::CreateAnd(TruncY,
X);
1994 while (!WorkList.
empty()) {
1995 auto MatchOrOperatorArgument = [&](
Value *OrOperatorArgument) {
1998 if (
match(OrOperatorArgument,
2004 if (
match(OrOperatorArgument,
2014 Value *OrOperatorLhs, *OrOperatorRhs;
2016 if (!
match(CurrentValue,
2021 MatchOrOperatorArgument(OrOperatorRhs);
2022 MatchOrOperatorArgument(OrOperatorLhs);
2028 CmpValues.
rbegin()->second);
2030 for (
auto It = CmpValues.
rbegin() + 1; It != CmpValues.
rend(); ++It) {
2032 LhsCmp = Builder.
CreateBinOp(BOpc, LhsCmp, RhsCmp);
2048 ConstantInt::get(V->getType(), 1));
2051 Value *OrOp0 =
Or->getOperand(0), *OrOp1 =
Or->getOperand(1);
2056 cast<PossiblyDisjointInst>(
Or)->isDisjoint()) {
2059 return new ICmpInst(Pred, OrOp0, NewC);
2063 if (
match(OrOp1,
m_APInt(MaskC)) && Cmp.isEquality()) {
2064 if (*MaskC ==
C && (
C + 1).isPowerOf2()) {
2069 return new ICmpInst(Pred, OrOp0, OrOp1);
2076 if (
Or->hasOneUse()) {
2078 Constant *NewC = ConstantInt::get(
Or->getType(),
C ^ (*MaskC));
2090 Constant *NewC = ConstantInt::get(
X->getType(), TrueIfSigned ? 1 : 0);
2118 if (!Cmp.isEquality() || !
C.isZero() || !
Or->hasOneUse())
2150 if (Cmp.isEquality() &&
C.isZero() &&
X ==
Mul->getOperand(1) &&
2151 (
Mul->hasNoUnsignedWrap() ||
Mul->hasNoSignedWrap()))
2173 if (Cmp.isEquality()) {
2175 if (
Mul->hasNoSignedWrap() &&
C.srem(*MulC).isZero()) {
2176 Constant *NewC = ConstantInt::get(MulTy,
C.sdiv(*MulC));
2184 if (
C.urem(*MulC).isZero()) {
2187 if ((*MulC & 1).isOne() ||
Mul->hasNoUnsignedWrap()) {
2188 Constant *NewC = ConstantInt::get(MulTy,
C.udiv(*MulC));
2201 if (
C.isMinSignedValue() && MulC->
isAllOnes())
2207 NewC = ConstantInt::get(
2211 "Unexpected predicate");
2212 NewC = ConstantInt::get(
2217 NewC = ConstantInt::get(
2221 "Unexpected predicate");
2222 NewC = ConstantInt::get(
2227 return NewC ?
new ICmpInst(Pred,
X, NewC) :
nullptr;
2238 unsigned TypeBits =
C.getBitWidth();
2239 bool CIsPowerOf2 =
C.isPowerOf2();
2241 if (Cmp.isUnsigned()) {
2254 unsigned CLog2 =
C.logBase2();
2255 return new ICmpInst(Pred,
Y, ConstantInt::get(ShiftType, CLog2));
2256 }
else if (Cmp.isSigned()) {
2257 Constant *BitWidthMinusOne = ConstantInt::get(ShiftType, TypeBits - 1);
2278 const APInt *ShiftVal;
2308 const APInt *ShiftAmt;
2314 unsigned TypeBits =
C.getBitWidth();
2315 if (ShiftAmt->
uge(TypeBits))
2327 APInt ShiftedC =
C.ashr(*ShiftAmt);
2328 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2331 C.ashr(*ShiftAmt).shl(*ShiftAmt) ==
C) {
2332 APInt ShiftedC =
C.ashr(*ShiftAmt);
2333 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2340 assert(!
C.isMinSignedValue() &&
"Unexpected icmp slt");
2341 APInt ShiftedC = (
C - 1).ashr(*ShiftAmt) + 1;
2342 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2352 APInt ShiftedC =
C.lshr(*ShiftAmt);
2353 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2356 C.lshr(*ShiftAmt).shl(*ShiftAmt) ==
C) {
2357 APInt ShiftedC =
C.lshr(*ShiftAmt);
2358 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2365 assert(
C.ugt(0) &&
"ult 0 should have been eliminated");
2366 APInt ShiftedC = (
C - 1).lshr(*ShiftAmt) + 1;
2367 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2371 if (Cmp.isEquality() && Shl->
hasOneUse()) {
2377 Constant *LShrC = ConstantInt::get(ShType,
C.lshr(*ShiftAmt));
2382 bool TrueIfSigned =
false;
2394 if (Cmp.isUnsigned() && Shl->
hasOneUse()) {
2396 if ((
C + 1).isPowerOf2() &&
2404 if (
C.isPowerOf2() &&
2433 if (
auto FlippedStrictness =
2435 Pred, ConstantInt::get(ShType->
getContext(),
C))) {
2436 CmpPred = FlippedStrictness->first;
2437 RHSC = cast<ConstantInt>(FlippedStrictness->second)->getValue();
2444 ConstantInt::get(TruncTy, RHSC.
ashr(*ShiftAmt).
trunc(TypeBits - Amt));
2463 if (Cmp.isEquality() && Shr->
isExact() &&
C.isZero())
2464 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
2466 bool IsAShr = Shr->
getOpcode() == Instruction::AShr;
2467 const APInt *ShiftValC;
2469 if (Cmp.isEquality())
2487 assert(ShiftValC->
uge(
C) &&
"Expected simplify of compare");
2488 assert((IsUGT || !
C.isZero()) &&
"Expected X u< 0 to simplify");
2490 unsigned CmpLZ = IsUGT ?
C.countl_zero() : (
C - 1).
countl_zero();
2498 const APInt *ShiftAmtC;
2504 unsigned TypeBits =
C.getBitWidth();
2506 if (ShAmtVal >= TypeBits || ShAmtVal == 0)
2509 bool IsExact = Shr->
isExact();
2517 (
C - 1).isPowerOf2() &&
C.countLeadingZeros() > ShAmtVal) {
2523 APInt ShiftedC = (
C - 1).shl(ShAmtVal) + 1;
2524 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2530 APInt ShiftedC =
C.shl(ShAmtVal);
2531 if (ShiftedC.
ashr(ShAmtVal) ==
C)
2532 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2536 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2537 if (!
C.isMaxSignedValue() && !(
C + 1).shl(ShAmtVal).isMinSignedValue() &&
2538 (ShiftedC + 1).ashr(ShAmtVal) == (
C + 1))
2539 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2545 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2546 if ((ShiftedC + 1).ashr(ShAmtVal) == (
C + 1) ||
2547 (
C + 1).shl(ShAmtVal).isMinSignedValue())
2548 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2555 if (
C.getBitWidth() > 2 &&
C.getNumSignBits() <= ShAmtVal) {
2565 }
else if (!IsAShr) {
2569 APInt ShiftedC =
C.shl(ShAmtVal);
2570 if (ShiftedC.
lshr(ShAmtVal) ==
C)
2571 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2575 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2576 if ((ShiftedC + 1).lshr(ShAmtVal) == (
C + 1))
2577 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2581 if (!Cmp.isEquality())
2589 assert(((IsAShr &&
C.shl(ShAmtVal).ashr(ShAmtVal) ==
C) ||
2590 (!IsAShr &&
C.shl(ShAmtVal).lshr(ShAmtVal) ==
C)) &&
2591 "Expected icmp+shr simplify did not occur.");
2596 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy,
C << ShAmtVal));
2602 ConstantInt::get(ShrTy, (
C + 1).shl(ShAmtVal)));
2605 ConstantInt::get(ShrTy, (
C + 1).shl(ShAmtVal) - 1));
2612 Constant *Mask = ConstantInt::get(ShrTy, Val);
2614 return new ICmpInst(Pred,
And, ConstantInt::get(ShrTy,
C << ShAmtVal));
2637 const APInt *DivisorC;
2646 !
C.isStrictlyPositive()))
2652 Constant *MaskC = ConstantInt::get(Ty, SignMask | (*DivisorC - 1));
2656 return new ICmpInst(Pred,
And, ConstantInt::get(Ty,
C));
2683 assert(*C2 != 0 &&
"udiv 0, X should have been simplified already.");
2688 "icmp ugt X, UINT_MAX should have been simplified already.");
2690 ConstantInt::get(Ty, C2->
udiv(
C + 1)));
2695 assert(
C != 0 &&
"icmp ult X, 0 should have been simplified already.");
2697 ConstantInt::get(Ty, C2->
udiv(
C)));
2711 bool DivIsSigned = Div->
getOpcode() == Instruction::SDiv;
2721 if (Cmp.isEquality() && Div->
hasOneUse() &&
C.isSignBitSet() &&
2722 (!DivIsSigned ||
C.isMinSignedValue())) {
2747 if (!Cmp.isEquality() && DivIsSigned != Cmp.isSigned())
2766 bool ProdOV = (DivIsSigned ? Prod.
sdiv(*C2) : Prod.
udiv(*C2)) !=
C;
2779 int LoOverflow = 0, HiOverflow = 0;
2780 APInt LoBound, HiBound;
2785 HiOverflow = LoOverflow = ProdOV;
2794 LoBound = -(RangeSize - 1);
2795 HiBound = RangeSize;
2796 }
else if (
C.isStrictlyPositive()) {
2798 HiOverflow = LoOverflow = ProdOV;
2804 LoOverflow = HiOverflow = ProdOV ? -1 : 0;
2806 APInt DivNeg = -RangeSize;
2807 LoOverflow =
addWithOverflow(LoBound, HiBound, DivNeg,
true) ? -1 : 0;
2815 LoBound = RangeSize + 1;
2816 HiBound = -RangeSize;
2817 if (HiBound == *C2) {
2821 }
else if (
C.isStrictlyPositive()) {
2824 HiOverflow = LoOverflow = ProdOV ? -1 : 0;
2830 LoOverflow = HiOverflow = ProdOV;
2843 if (LoOverflow && HiOverflow)
2847 X, ConstantInt::get(Ty, LoBound));
2850 X, ConstantInt::get(Ty, HiBound));
2854 if (LoOverflow && HiOverflow)
2858 X, ConstantInt::get(Ty, LoBound));
2861 X, ConstantInt::get(Ty, HiBound));
2866 if (LoOverflow == +1)
2868 if (LoOverflow == -1)
2870 return new ICmpInst(Pred,
X, ConstantInt::get(Ty, LoBound));
2873 if (HiOverflow == +1)
2875 if (HiOverflow == -1)
2908 ((Cmp.isUnsigned() && HasNUW) || (Cmp.isSigned() && HasNSW)) &&
2910 return new ICmpInst(SwappedPred,
Y, ConstantInt::get(Ty, SubResult));
2918 if (Cmp.isEquality() &&
C.isZero() &&
2954 (*C2 & (
C - 1)) == (
C - 1))
2967 return new ICmpInst(SwappedPred,
Add, ConstantInt::get(Ty, ~
C));
2973 auto FoldConstant = [&](
bool Val) {
2977 cast<VectorType>(Op0->
getType())->getElementCount(), Res);
2981 switch (Table.to_ulong()) {
2983 return FoldConstant(
false);
3013 return FoldConstant(
true);
3036 unsigned BW =
C.getBitWidth();
3037 std::bitset<4> Table;
3038 auto ComputeTable = [&](
bool Op0Val,
bool Op1Val) {
3041 Res += isa<ZExtInst>(Ext0) ? 1 : -1;
3043 Res += isa<ZExtInst>(Ext1) ? 1 : -1;
3047 Table[0] = ComputeTable(
false,
false);
3048 Table[1] = ComputeTable(
false,
true);
3049 Table[2] = ComputeTable(
true,
false);
3050 Table[3] = ComputeTable(
true,
true);
3065 if ((
Add->hasNoSignedWrap() &&
3067 (
Add->hasNoUnsignedWrap() &&
3071 Cmp.isSigned() ?
C.ssub_ov(*C2, Overflow) :
C.usub_ov(*C2, Overflow);
3077 return new ICmpInst(Pred,
X, ConstantInt::get(Ty, NewC));
3081 C.isNonNegative() && (
C - *C2).isNonNegative() &&
3084 ConstantInt::get(Ty,
C - *C2));
3089 if (Cmp.isSigned()) {
3090 if (
Lower.isSignMask())
3092 if (
Upper.isSignMask())
3095 if (
Lower.isMinValue())
3097 if (
Upper.isMinValue())
3130 if (!
Add->hasOneUse())
3145 ConstantInt::get(Ty,
C * 2));
3160 ConstantInt::get(Ty, ~
C));
3180 Value *EqualVal = SI->getTrueValue();
3181 Value *UnequalVal = SI->getFalseValue();
3204 auto FlippedStrictness =
3206 PredB, cast<Constant>(RHS2));
3207 if (!FlippedStrictness)
3210 "basic correctness failure");
3211 RHS2 = FlippedStrictness->second;
3223 assert(
C &&
"Cmp RHS should be a constant int!");
3229 Value *OrigLHS, *OrigRHS;
3230 ConstantInt *C1LessThan, *C2Equal, *C3GreaterThan;
3231 if (Cmp.hasOneUse() &&
3234 assert(C1LessThan && C2Equal && C3GreaterThan);
3237 C1LessThan->
getValue(),
C->getValue(), Cmp.getPredicate());
3239 Cmp.getPredicate());
3241 C3GreaterThan->
getValue(),
C->getValue(), Cmp.getPredicate());
3252 if (TrueWhenLessThan)
3258 if (TrueWhenGreaterThan)
3268 auto *Bitcast = dyn_cast<BitCastInst>(Cmp.getOperand(0));
3273 Value *Op1 = Cmp.getOperand(1);
3274 Value *BCSrcOp = Bitcast->getOperand(0);
3275 Type *SrcType = Bitcast->getSrcTy();
3276 Type *DstType = Bitcast->getType();
3296 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(), 1));
3323 Type *XType =
X->getType();
3328 if (
auto *XVTy = dyn_cast<VectorType>(XType))
3342 if (!Cmp.getParent()->getParent()->hasFnAttribute(
3343 Attribute::NoImplicitFloat) &&
3368 if (Cmp.isEquality() &&
C->isAllOnes() && Bitcast->hasOneUse()) {
3369 if (
Value *NotBCSrcOp =
3380 if (Cmp.isEquality() &&
C->isZero() && Bitcast->hasOneUse() &&
3382 if (
auto *VecTy = dyn_cast<FixedVectorType>(
X->getType())) {
3401 auto *VecTy = cast<VectorType>(SrcType);
3402 auto *EltTy = cast<IntegerType>(VecTy->getElementType());
3403 if (
C->isSplat(EltTy->getBitWidth())) {
3411 Value *NewC = ConstantInt::get(EltTy,
C->trunc(EltTy->getBitWidth()));
3412 return new ICmpInst(Pred, Extract, NewC);
3425 if (
auto *BO = dyn_cast<BinaryOperator>(Cmp.getOperand(0)))
3429 if (
auto *SI = dyn_cast<SelectInst>(Cmp.getOperand(0)))
3433 if (
auto *ConstRHS = dyn_cast<ConstantInt>(Cmp.getOperand(1)))
3437 if (
auto *TI = dyn_cast<TruncInst>(Cmp.getOperand(0)))
3441 if (
auto *
II = dyn_cast<IntrinsicInst>(Cmp.getOperand(0)))
3448 Value *Cmp0 = Cmp.getOperand(0);
3450 if (
C->isZero() && Cmp.isEquality() && Cmp0->
hasOneUse() &&
3452 m_ExtractValue<0>(m_Intrinsic<Intrinsic::ssub_with_overflow>(
3455 m_ExtractValue<0>(m_Intrinsic<Intrinsic::usub_with_overflow>(
3457 return new ICmpInst(Cmp.getPredicate(),
X,
Y);
3472 if (!Cmp.isEquality())
3477 Constant *
RHS = cast<Constant>(Cmp.getOperand(1));
3481 case Instruction::SRem:
3492 case Instruction::Add: {
3496 if (
Constant *C2 = dyn_cast<Constant>(BOp1)) {
3499 }
else if (
C.isZero()) {
3502 if (
Value *NegVal = dyn_castNegVal(BOp1))
3503 return new ICmpInst(Pred, BOp0, NegVal);
3504 if (
Value *NegVal = dyn_castNegVal(BOp0))
3505 return new ICmpInst(Pred, NegVal, BOp1);
3514 return new ICmpInst(Pred, BOp0, Neg);
3519 case Instruction::Xor:
3520 if (
Constant *BOC = dyn_cast<Constant>(BOp1)) {
3524 }
else if (
C.isZero()) {
3526 return new ICmpInst(Pred, BOp0, BOp1);
3529 case Instruction::Or: {
3587 case Instruction::UDiv:
3588 case Instruction::SDiv:
3598 return new ICmpInst(Pred, BOp0, BOp1);
3601 Instruction::Mul, BO->
getOpcode() == Instruction::SDiv, BOp1,
3602 Cmp.getOperand(1), BO);
3606 return new ICmpInst(Pred, YC, BOp0);
3610 if (BO->
getOpcode() == Instruction::UDiv &&
C.isZero()) {
3613 return new ICmpInst(NewPred, BOp1, BOp0);
3627 "Non-ctpop intrin in ctpop fold");
3663 Type *Ty =
II->getType();
3667 switch (
II->getIntrinsicID()) {
3668 case Intrinsic::abs:
3671 if (
C.isZero() ||
C.isMinSignedValue())
3672 return new ICmpInst(Pred,
II->getArgOperand(0), ConstantInt::get(Ty,
C));
3675 case Intrinsic::bswap:
3677 return new ICmpInst(Pred,
II->getArgOperand(0),
3678 ConstantInt::get(Ty,
C.byteSwap()));
3680 case Intrinsic::bitreverse:
3682 return new ICmpInst(Pred,
II->getArgOperand(0),
3683 ConstantInt::get(Ty,
C.reverseBits()));
3685 case Intrinsic::ctlz:
3686 case Intrinsic::cttz: {
3689 return new ICmpInst(Pred,
II->getArgOperand(0),
3695 unsigned Num =
C.getLimitedValue(
BitWidth);
3697 bool IsTrailing =
II->getIntrinsicID() == Intrinsic::cttz;
3700 APInt Mask2 = IsTrailing
3704 ConstantInt::get(Ty, Mask2));
3709 case Intrinsic::ctpop: {
3712 bool IsZero =
C.isZero();
3714 return new ICmpInst(Pred,
II->getArgOperand(0),
3721 case Intrinsic::fshl:
3722 case Intrinsic::fshr:
3723 if (
II->getArgOperand(0) ==
II->getArgOperand(1)) {
3724 const APInt *RotAmtC;
3728 return new ICmpInst(Pred,
II->getArgOperand(0),
3729 II->getIntrinsicID() == Intrinsic::fshl
3730 ? ConstantInt::get(Ty,
C.rotr(*RotAmtC))
3731 : ConstantInt::get(Ty,
C.rotl(*RotAmtC)));
3735 case Intrinsic::umax:
3736 case Intrinsic::uadd_sat: {
3739 if (
C.isZero() &&
II->hasOneUse()) {
3746 case Intrinsic::ssub_sat:
3749 return new ICmpInst(Pred,
II->getArgOperand(0),
II->getArgOperand(1));
3751 case Intrinsic::usub_sat: {
3756 return new ICmpInst(NewPred,
II->getArgOperand(0),
II->getArgOperand(1));
3771 assert(Cmp.isEquality());
3774 Value *Op0 = Cmp.getOperand(0);
3775 Value *Op1 = Cmp.getOperand(1);
3776 const auto *IIOp0 = dyn_cast<IntrinsicInst>(Op0);
3777 const auto *IIOp1 = dyn_cast<IntrinsicInst>(Op1);
3778 if (!IIOp0 || !IIOp1 || IIOp0->getIntrinsicID() != IIOp1->getIntrinsicID())
3781 switch (IIOp0->getIntrinsicID()) {
3782 case Intrinsic::bswap:
3783 case Intrinsic::bitreverse:
3786 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
3787 case Intrinsic::fshl:
3788 case Intrinsic::fshr: {
3791 if (IIOp0->getOperand(0) != IIOp0->getOperand(1))
3793 if (IIOp1->getOperand(0) != IIOp1->getOperand(1))
3795 if (IIOp0->getOperand(2) == IIOp1->getOperand(2))
3796 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
3802 unsigned OneUses = IIOp0->hasOneUse() + IIOp1->hasOneUse();
3807 Builder.
CreateSub(IIOp0->getOperand(2), IIOp1->getOperand(2));
3809 Op0->
getType(), IIOp0->getIntrinsicID(),
3810 {IIOp0->getOperand(0), IIOp0->getOperand(0), SubAmt});
3811 return new ICmpInst(Pred, IIOp1->getOperand(0), CombinedRotate);
3828 if (
auto *
II = dyn_cast<IntrinsicInst>(Cmp.getOperand(0))) {
3829 switch (
II->getIntrinsicID()) {
3832 case Intrinsic::fshl:
3833 case Intrinsic::fshr:
3834 if (Cmp.isEquality() &&
II->getArgOperand(0) ==
II->getArgOperand(1)) {
3836 if (
C.isZero() ||
C.isAllOnes())
3837 return new ICmpInst(Pred,
II->getArgOperand(0), Cmp.getOperand(1));
3851 case Instruction::Xor:
3855 case Instruction::And:
3859 case Instruction::Or:
3863 case Instruction::Mul:
3867 case Instruction::Shl:
3871 case Instruction::LShr:
3872 case Instruction::AShr:
3876 case Instruction::SRem:
3880 case Instruction::UDiv:
3884 case Instruction::SDiv:
3888 case Instruction::Sub:
3892 case Instruction::Add:
3910 if (!
II->hasOneUse())
3926 Value *Op0 =
II->getOperand(0);
3927 Value *Op1 =
II->getOperand(1);
3936 switch (
II->getIntrinsicID()) {
3939 "This function only works with usub_sat and uadd_sat for now!");
3940 case Intrinsic::uadd_sat:
3943 case Intrinsic::usub_sat:
3953 II->getBinaryOp(), *COp1,
II->getNoWrapKind());
3960 if (
II->getBinaryOp() == Instruction::Add)
3966 SatValCheck ? Instruction::BinaryOps::Or : Instruction::BinaryOps::And;
3968 std::optional<ConstantRange> Combination;
3969 if (CombiningOp == Instruction::BinaryOps::Or)
3981 Combination->getEquivalentICmp(EquivPred, EquivInt, EquivOffset);
3986 ConstantInt::get(Op1->
getType(), EquivInt));
3993 std::optional<ICmpInst::Predicate> NewPredicate = std::nullopt;
3998 NewPredicate = Pred;
4002 else if (
C.isAllOnes())
4010 else if (
C.isZero())
4027 if (!
C.isZero() && !
C.isAllOnes())
4038 if (
I->getIntrinsicID() == Intrinsic::scmp)
4052 switch (
II->getIntrinsicID()) {
4055 case Intrinsic::uadd_sat:
4056 case Intrinsic::usub_sat:
4061 case Intrinsic::ctpop: {
4066 case Intrinsic::scmp:
4067 case Intrinsic::ucmp:
4073 if (Cmp.isEquality())
4076 Type *Ty =
II->getType();
4078 switch (
II->getIntrinsicID()) {
4079 case Intrinsic::ctpop: {
4091 case Intrinsic::ctlz: {
4094 unsigned Num =
C.getLimitedValue();
4097 II->getArgOperand(0), ConstantInt::get(Ty, Limit));
4102 unsigned Num =
C.getLimitedValue();
4105 II->getArgOperand(0), ConstantInt::get(Ty, Limit));
4109 case Intrinsic::cttz: {
4111 if (!
II->hasOneUse())
4131 case Intrinsic::ssub_sat:
4135 return new ICmpInst(Pred,
II->getArgOperand(0),
II->getArgOperand(1));
4139 II->getArgOperand(1));
4143 II->getArgOperand(1));
4155 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
4156 Constant *RHSC = dyn_cast<Constant>(Op1);
4162 case Instruction::PHI:
4166 case Instruction::IntToPtr:
4175 case Instruction::Load:
4178 dyn_cast<GetElementPtrInst>(LHSI->
getOperand(0)))
4194 auto SimplifyOp = [&](
Value *
Op,
bool SelectCondIsTrue) ->
Value * {
4198 SI->getCondition(), Pred,
Op,
RHS,
DL, SelectCondIsTrue))
4199 return ConstantInt::get(
I.getType(), *Impl);
4204 Value *Op1 = SimplifyOp(SI->getOperand(1),
true);
4206 CI = dyn_cast<ConstantInt>(Op1);
4208 Value *Op2 = SimplifyOp(SI->getOperand(2),
false);
4210 CI = dyn_cast<ConstantInt>(Op2);
4219 bool Transform =
false;
4222 else if (Op1 || Op2) {
4224 if (SI->hasOneUse())
4227 else if (CI && !CI->
isZero())
4246 unsigned Depth = 0) {
4249 if (V->getType()->getScalarSizeInBits() == 1)
4257 switch (
I->getOpcode()) {
4258 case Instruction::ZExt:
4261 case Instruction::SExt:
4265 case Instruction::And:
4266 case Instruction::Or:
4273 case Instruction::Xor:
4283 case Instruction::Select:
4287 case Instruction::Shl:
4290 case Instruction::LShr:
4293 case Instruction::AShr:
4297 case Instruction::Add:
4303 case Instruction::Sub:
4309 case Instruction::Call: {
4310 if (
auto *
II = dyn_cast<IntrinsicInst>(
I)) {
4311 switch (
II->getIntrinsicID()) {
4314 case Intrinsic::umax:
4315 case Intrinsic::smax:
4316 case Intrinsic::umin:
4317 case Intrinsic::smin:
4322 case Intrinsic::bitreverse:
4412 auto IsLowBitMask = [&]() {
4430 auto Check = [&]() {
4448 auto Check = [&]() {
4467 if (!IsLowBitMask())
4486 const APInt *C0, *C1;
4503 const APInt &MaskedBits = *C0;
4504 assert(MaskedBits != 0 &&
"shift by zero should be folded away already.");
4525 auto *XType =
X->getType();
4526 const unsigned XBitWidth = XType->getScalarSizeInBits();
4528 assert(
BitWidth.ugt(MaskedBits) &&
"shifts should leave some bits untouched");
4559 !
I.getOperand(0)->hasOneUse())
4584 assert(NarrowestTy ==
I.getOperand(0)->getType() &&
4585 "We did not look past any shifts while matching XShift though.");
4586 bool HadTrunc = WidestTy !=
I.getOperand(0)->getType();
4593 auto XShiftOpcode = XShift->
getOpcode();
4594 if (XShiftOpcode == YShift->
getOpcode())
4597 Value *
X, *XShAmt, *
Y, *YShAmt;
4604 if (!isa<Constant>(
X) && !isa<Constant>(
Y)) {
4606 if (!
match(
I.getOperand(0),
4632 unsigned MaximalPossibleTotalShiftAmount =
4635 APInt MaximalRepresentableShiftAmount =
4637 if (MaximalRepresentableShiftAmount.
ult(MaximalPossibleTotalShiftAmount))
4641 auto *NewShAmt = dyn_cast_or_null<Constant>(
4646 if (NewShAmt->getType() != WidestTy) {
4656 if (!
match(NewShAmt,
4658 APInt(WidestBitWidth, WidestBitWidth))))
4663 auto CanFold = [NewShAmt, WidestBitWidth, NarrowestShift, SQ,
4669 ? NewShAmt->getSplatValue()
4672 if (NewShAmtSplat &&
4678 if (
auto *
C = dyn_cast<Constant>(NarrowestShift->getOperand(0))) {
4682 unsigned MaxActiveBits = Known.
getBitWidth() - MinLeadZero;
4683 if (MaxActiveBits <= 1)
4689 if (
auto *
C = dyn_cast<Constant>(WidestShift->
getOperand(0))) {
4693 unsigned MaxActiveBits = Known.
getBitWidth() - MinLeadZero;
4694 if (MaxActiveBits <= 1)
4697 if (NewShAmtSplat) {
4700 if (AdjNewShAmt.
ule(MinLeadZero))
4714 Value *T0 = XShiftOpcode == Instruction::BinaryOps::LShr
4736 if (!
I.isEquality() &&
4746 NeedNegation =
false;
4749 NeedNegation =
true;
4755 if (
I.isEquality() &&
4771 bool MulHadOtherUses =
Mul && !
Mul->hasOneUse();
4772 if (MulHadOtherUses)
4777 ? Intrinsic::umul_with_overflow
4778 : Intrinsic::smul_with_overflow,
4785 if (MulHadOtherUses)
4794 if (MulHadOtherUses)
4820 Type *Ty =
X->getType();
4834 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
4896 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
4931 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
4947 return new ICmpInst(PredOut, Op0, Op1);
4959 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5015 return new ICmpInst(NewPred, Op1, Zero);
5024 return new ICmpInst(NewPred, Op0, Zero);
5028 bool NoOp0WrapProblem =
false, NoOp1WrapProblem =
false;
5029 bool Op0HasNUW =
false, Op1HasNUW =
false;
5030 bool Op0HasNSW =
false, Op1HasNSW =
false;
5034 bool &HasNSW,
bool &HasNUW) ->
bool {
5035 if (isa<OverflowingBinaryOperator>(BO)) {
5041 }
else if (BO.
getOpcode() == Instruction::Or) {
5049 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr;
5053 NoOp0WrapProblem = hasNoWrapProblem(*BO0, Pred, Op0HasNSW, Op0HasNUW);
5057 NoOp1WrapProblem = hasNoWrapProblem(*BO1, Pred, Op1HasNSW, Op1HasNUW);
5062 if ((
A == Op1 ||
B == Op1) && NoOp0WrapProblem)
5068 if ((
C == Op0 ||
D == Op0) && NoOp1WrapProblem)
5073 if (
A &&
C && (
A ==
C ||
A ==
D ||
B ==
C ||
B ==
D) && NoOp0WrapProblem &&
5081 }
else if (
A ==
D) {
5085 }
else if (
B ==
C) {
5166 if (
A &&
C && NoOp0WrapProblem && NoOp1WrapProblem &&
5168 const APInt *AP1, *AP2;
5176 if (AP1Abs.
uge(AP2Abs)) {
5177 APInt Diff = *AP1 - *AP2;
5180 A, C3,
"", Op0HasNUW && Diff.
ule(*AP1), Op0HasNSW);
5183 APInt Diff = *AP2 - *AP1;
5186 C, C3,
"", Op1HasNUW && Diff.
ule(*AP2), Op1HasNSW);
5205 if (BO0 && BO0->
getOpcode() == Instruction::Sub) {
5209 if (BO1 && BO1->
getOpcode() == Instruction::Sub) {
5215 if (
A == Op1 && NoOp0WrapProblem)
5218 if (
C == Op0 && NoOp1WrapProblem)
5238 if (
B &&
D &&
B ==
D && NoOp0WrapProblem && NoOp1WrapProblem)
5242 if (
A &&
C &&
A ==
C && NoOp0WrapProblem && NoOp1WrapProblem)
5249 if (
Constant *RHSC = dyn_cast<Constant>(Op1))
5250 if (RHSC->isNotMinSignedValue())
5251 return new ICmpInst(
I.getSwappedPredicate(),
X,
5279 if (NonZero && BO0 && BO1 && Op0HasNSW && Op1HasNSW)
5286 if (NonZero && BO0 && BO1 && Op0HasNUW && Op1HasNUW)
5296 else if (BO1 && BO1->
getOpcode() == Instruction::SRem &&
5326 case Instruction::Add:
5327 case Instruction::Sub:
5328 case Instruction::Xor: {
5335 if (
C->isSignMask()) {
5341 if (BO0->
getOpcode() == Instruction::Xor &&
C->isMaxSignedValue()) {
5343 NewPred =
I.getSwappedPredicate(NewPred);
5349 case Instruction::Mul: {
5350 if (!
I.isEquality())
5358 if (
unsigned TZs =
C->countr_zero()) {
5364 return new ICmpInst(Pred, And1, And2);
5369 case Instruction::UDiv:
5370 case Instruction::LShr:
5375 case Instruction::SDiv:
5381 case Instruction::AShr:
5386 case Instruction::Shl: {
5387 bool NUW = Op0HasNUW && Op1HasNUW;
5388 bool NSW = Op0HasNSW && Op1HasNSW;
5391 if (!NSW &&
I.isSigned())
5456 auto IsCondKnownTrue = [](
Value *Val) -> std::optional<bool> {
5458 return std::nullopt;
5463 return std::nullopt;
5467 if (!CmpXZ.has_value() && !CmpYZ.has_value())
5469 if (!CmpXZ.has_value()) {
5475 if (CmpYZ.has_value())
5499 if (!MinMaxCmpXZ.has_value()) {
5507 if (!MinMaxCmpXZ.has_value())
5523 return FoldIntoCmpYZ();
5550 return FoldIntoCmpYZ();
5559 return FoldIntoCmpYZ();
5581 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5585 if (
I.isEquality()) {
5620 Type *Ty =
A->getType();
5623 ConstantInt::get(Ty, 2))
5625 ConstantInt::get(Ty, 1));
5632 if (!
I.isEquality())
5635 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5639 if (
A == Op1 ||
B == Op1) {
5640 Value *OtherVal =
A == Op1 ?
B :
A;
5668 Value *OtherVal =
A == Op0 ?
B :
A;
5675 Value *
X =
nullptr, *
Y =
nullptr, *Z =
nullptr;
5681 }
else if (
A ==
D) {
5685 }
else if (
B ==
C) {
5689 }
else if (
B ==
D) {
5699 const APInt *C0, *C1;
5701 (*C0 ^ *C1).isNegatedPowerOf2();
5707 int(Op0->
hasOneUse()) + int(Op1->hasOneUse()) +
5709 if (XorIsNegP2 || UseCnt >= 2) {
5732 (Op0->
hasOneUse() || Op1->hasOneUse())) {
5737 MaskC->
countr_one() ==
A->getType()->getScalarSizeInBits())
5743 const APInt *AP1, *AP2;
5752 if (ShAmt < TypeBits && ShAmt != 0) {
5757 return new ICmpInst(NewPred,
Xor, ConstantInt::get(
A->getType(), CmpVal));
5767 if (ShAmt < TypeBits && ShAmt != 0) {
5771 I.getName() +
".mask");
5785 unsigned ASize = cast<IntegerType>(
A->getType())->getPrimitiveSizeInBits();
5787 if (ShAmt < ASize) {
5810 A->getType()->getScalarSizeInBits() ==
BitWidth * 2 &&
5811 (
I.getOperand(0)->hasOneUse() ||
I.getOperand(1)->hasOneUse())) {
5816 Add, ConstantInt::get(
A->getType(),
C.shl(1)));
5839 m_OneUse(m_Intrinsic<Intrinsic::fshr>(
5858 std::optional<bool> IsZero = std::nullopt;
5901 unsigned SrcBits =
X->getType()->getScalarSizeInBits();
5905 Constant *MaskC = ConstantInt::get(
X->getType(),
C->zext(SrcBits));
5913 Constant *MaskC = ConstantInt::get(
X->getType(), (*
C + 1).zext(SrcBits));
5918 if (
auto *
II = dyn_cast<IntrinsicInst>(
X)) {
5919 if (
II->getIntrinsicID() == Intrinsic::cttz ||
5920 II->getIntrinsicID() == Intrinsic::ctlz) {
5921 unsigned MaxRet = SrcBits;
5941 assert(isa<CastInst>(ICmp.
getOperand(0)) &&
"Expected cast for operand 0");
5942 auto *CastOp0 = cast<CastInst>(ICmp.
getOperand(0));
5947 bool IsSignedExt = CastOp0->getOpcode() == Instruction::SExt;
5948 bool IsSignedCmp = ICmp.
isSigned();
5953 bool IsZext0 = isa<ZExtInst>(ICmp.
getOperand(0));
5954 bool IsZext1 = isa<ZExtInst>(ICmp.
getOperand(1));
5956 if (IsZext0 != IsZext1) {
5961 if (ICmp.
isEquality() &&
X->getType()->isIntOrIntVectorTy(1) &&
5962 Y->getType()->isIntOrIntVectorTy(1))
5969 auto *NonNegInst0 = dyn_cast<PossiblyNonNegInst>(ICmp.
getOperand(0));
5970 auto *NonNegInst1 = dyn_cast<PossiblyNonNegInst>(ICmp.
getOperand(1));
5972 bool IsNonNeg0 = NonNegInst0 && NonNegInst0->hasNonNeg();
5973 bool IsNonNeg1 = NonNegInst1 && NonNegInst1->hasNonNeg();
5975 if ((IsZext0 && IsNonNeg0) || (IsZext1 && IsNonNeg1))
5982 Type *XTy =
X->getType(), *YTy =
Y->getType();
5989 IsSignedExt ? Instruction::SExt : Instruction::ZExt;
6005 if (IsSignedCmp && IsSignedExt)
6018 Type *SrcTy = CastOp0->getSrcTy();
6026 if (IsSignedExt && IsSignedCmp)
6038 if (IsSignedCmp || !IsSignedExt || !isa<ConstantInt>(
C))
6057 Value *SimplifiedOp0 = simplifyIntToPtrRoundTripCast(ICmp.
getOperand(0));
6058 Value *SimplifiedOp1 = simplifyIntToPtrRoundTripCast(ICmp.
getOperand(1));
6059 if (SimplifiedOp0 || SimplifiedOp1)
6061 SimplifiedOp0 ? SimplifiedOp0 : ICmp.
getOperand(0),
6062 SimplifiedOp1 ? SimplifiedOp1 : ICmp.
getOperand(1));
6064 auto *CastOp0 = dyn_cast<CastInst>(ICmp.
getOperand(0));
6070 Value *Op0Src = CastOp0->getOperand(0);
6071 Type *SrcTy = CastOp0->getSrcTy();
6072 Type *DestTy = CastOp0->getDestTy();
6076 auto CompatibleSizes = [&](
Type *SrcTy,
Type *DestTy) {
6077 if (isa<VectorType>(SrcTy)) {
6078 SrcTy = cast<VectorType>(SrcTy)->getElementType();
6079 DestTy = cast<VectorType>(DestTy)->getElementType();
6083 if (CastOp0->getOpcode() == Instruction::PtrToInt &&
6084 CompatibleSizes(SrcTy, DestTy)) {
6085 Value *NewOp1 =
nullptr;
6086 if (
auto *PtrToIntOp1 = dyn_cast<PtrToIntOperator>(ICmp.
getOperand(1))) {
6087 Value *PtrSrc = PtrToIntOp1->getOperand(0);
6089 NewOp1 = PtrToIntOp1->getOperand(0);
6090 }
else if (
auto *RHSC = dyn_cast<Constant>(ICmp.
getOperand(1))) {
6108 case Instruction::Add:
6109 case Instruction::Sub:
6111 case Instruction::Mul:
6124 case Instruction::Add:
6129 case Instruction::Sub:
6134 case Instruction::Mul:
6143 bool IsSigned,
Value *LHS,
6147 if (OrigI.
isCommutative() && isa<Constant>(LHS) && !isa<Constant>(RHS))
6157 if (
auto *LHSTy = dyn_cast<VectorType>(
LHS->
getType()))
6172 Result->takeName(&OrigI);
6177 Result->takeName(&OrigI);
6179 if (
auto *Inst = dyn_cast<Instruction>(Result)) {
6181 Inst->setHasNoSignedWrap();
6183 Inst->setHasNoUnsignedWrap();
6206 const APInt *OtherVal,
6210 if (!isa<IntegerType>(MulVal->
getType()))
6213 auto *MulInstr = dyn_cast<Instruction>(MulVal);
6216 assert(MulInstr->getOpcode() == Instruction::Mul);
6218 auto *
LHS = cast<ZExtInst>(MulInstr->getOperand(0)),
6219 *
RHS = cast<ZExtInst>(MulInstr->getOperand(1));
6220 assert(
LHS->getOpcode() == Instruction::ZExt);
6221 assert(
RHS->getOpcode() == Instruction::ZExt);
6225 Type *TyA =
A->getType(), *TyB =
B->getType();
6227 WidthB = TyB->getPrimitiveSizeInBits();
6230 if (WidthB > WidthA) {
6245 if (
TruncInst *TI = dyn_cast<TruncInst>(U)) {
6248 if (TruncWidth > MulWidth)
6252 if (BO->getOpcode() != Instruction::And)
6254 if (
ConstantInt *CI = dyn_cast<ConstantInt>(BO->getOperand(1))) {
6255 const APInt &CVal = CI->getValue();
6271 switch (
I.getPredicate()) {
6278 if (MaxVal.
eq(*OtherVal))
6288 if (MaxVal.
eq(*OtherVal))
6302 if (WidthA < MulWidth)
6304 if (WidthB < MulWidth)
6307 I.getModule(), Intrinsic::umul_with_overflow, MulType);
6319 if (
TruncInst *TI = dyn_cast<TruncInst>(U)) {
6320 if (TI->getType()->getPrimitiveSizeInBits() == MulWidth)
6325 assert(BO->getOpcode() == Instruction::And);
6327 ConstantInt *CI = cast<ConstantInt>(BO->getOperand(1));
6363 switch (
I.getPredicate()) {
6394 assert(DI && UI &&
"Instruction not defined\n");
6405 auto *Usr = cast<Instruction>(U);
6406 if (Usr != UI && !
DT.
dominates(DB, Usr->getParent()))
6417 auto *BI = dyn_cast_or_null<BranchInst>(BB->
getTerminator());
6418 if (!BI || BI->getNumSuccessors() != 2)
6420 auto *IC = dyn_cast<ICmpInst>(BI->getCondition());
6421 if (!IC || (IC->getOperand(0) != SI && IC->getOperand(1) != SI))
6468 const unsigned SIOpd) {
6469 assert((SIOpd == 1 || SIOpd == 2) &&
"Invalid select operand!");
6471 BasicBlock *Succ = SI->getParent()->getTerminator()->getSuccessor(1);
6485 SI->replaceUsesOutsideBlock(SI->getOperand(SIOpd), SI->getParent());
6495 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6544 if (!isa<Constant>(Op0) && Op0Min == Op0Max)
6546 if (!isa<Constant>(Op1) && Op1Min == Op1Max)
6554 if (!Cmp.hasOneUse())
6563 if (!isMinMaxCmp(
I)) {
6568 if (Op1Min == Op0Max)
6573 if (*CmpC == Op0Min + 1)
6575 ConstantInt::get(Op1->getType(), *CmpC - 1));
6585 if (Op1Max == Op0Min)
6590 if (*CmpC == Op0Max - 1)
6592 ConstantInt::get(Op1->getType(), *CmpC + 1));
6602 if (Op1Min == Op0Max)
6606 if (*CmpC == Op0Min + 1)
6608 ConstantInt::get(Op1->getType(), *CmpC - 1));
6613 if (Op1Max == Op0Min)
6617 if (*CmpC == Op0Max - 1)
6619 ConstantInt::get(Op1->getType(), *CmpC + 1));
6633 if (Op0Max.
ult(Op1Min) || Op0Min.ugt(Op1Max))
6640 APInt Op0KnownZeroInverted = ~Op0Known.Zero;
6646 *LHSC != Op0KnownZeroInverted)
6652 Type *XTy =
X->getType();
6654 APInt C2 = Op0KnownZeroInverted;
6655 APInt C2Pow2 = (C2 & ~(*C1 - 1)) + *C1;
6661 auto *CmpC = ConstantInt::get(XTy, Log2C2 - Log2C1);
6671 (Op0Known & Op1Known) == Op0Known)
6677 if (Op0Max.
ult(Op1Min))
6679 if (Op0Min.uge(Op1Max))
6684 if (Op0Min.ugt(Op1Max))
6686 if (Op0Max.
ule(Op1Min))
6691 if (Op0Max.
slt(Op1Min))
6693 if (Op0Min.sge(Op1Max))
6698 if (Op0Min.sgt(Op1Max))
6700 if (Op0Max.
sle(Op1Min))
6705 assert(!isa<ConstantInt>(Op1) &&
"ICMP_SGE with ConstantInt not folded!");
6706 if (Op0Min.sge(Op1Max))
6708 if (Op0Max.
slt(Op1Min))
6710 if (Op1Min == Op0Max)
6714 assert(!isa<ConstantInt>(Op1) &&
"ICMP_SLE with ConstantInt not folded!");
6715 if (Op0Max.
sle(Op1Min))
6717 if (Op0Min.sgt(Op1Max))
6719 if (Op1Max == Op0Min)
6723 assert(!isa<ConstantInt>(Op1) &&
"ICMP_UGE with ConstantInt not folded!");
6724 if (Op0Min.uge(Op1Max))
6726 if (Op0Max.
ult(Op1Min))
6728 if (Op1Min == Op0Max)
6732 assert(!isa<ConstantInt>(Op1) &&
"ICMP_ULE with ConstantInt not folded!");
6733 if (Op0Max.
ule(Op1Min))
6735 if (Op0Min.ugt(Op1Max))
6737 if (Op1Max == Op0Min)
6747 return new ICmpInst(
I.getUnsignedPredicate(), Op0, Op1);
6779 bool IsSExt = ExtI->
getOpcode() == Instruction::SExt;
6781 auto CreateRangeCheck = [&] {
6796 }
else if (!IsSExt || HasOneUse) {
6801 return CreateRangeCheck();
6803 }
else if (IsSExt ?
C->isAllOnes() :
C->isOne()) {
6811 }
else if (!IsSExt || HasOneUse) {
6816 return CreateRangeCheck();
6830 Instruction::ICmp, Pred1,
X,
6840std::optional<std::pair<CmpInst::Predicate, Constant *>>
6844 "Only for relational integer predicates.");
6850 bool WillIncrement =
6855 auto ConstantIsOk = [WillIncrement, IsSigned](
ConstantInt *
C) {
6856 return WillIncrement ? !
C->isMaxValue(IsSigned) : !
C->isMinValue(IsSigned);
6859 Constant *SafeReplacementConstant =
nullptr;
6860 if (
auto *CI = dyn_cast<ConstantInt>(
C)) {
6862 if (!ConstantIsOk(CI))
6863 return std::nullopt;
6864 }
else if (
auto *FVTy = dyn_cast<FixedVectorType>(
Type)) {
6865 unsigned NumElts = FVTy->getNumElements();
6866 for (
unsigned i = 0; i != NumElts; ++i) {
6867 Constant *Elt =
C->getAggregateElement(i);
6869 return std::nullopt;
6871 if (isa<UndefValue>(Elt))
6876 auto *CI = dyn_cast<ConstantInt>(Elt);
6877 if (!CI || !ConstantIsOk(CI))
6878 return std::nullopt;
6880 if (!SafeReplacementConstant)
6881 SafeReplacementConstant = CI;
6883 }
else if (isa<VectorType>(
C->getType())) {
6885 Value *SplatC =
C->getSplatValue();
6886 auto *CI = dyn_cast_or_null<ConstantInt>(SplatC);
6888 if (!CI || !ConstantIsOk(CI))
6889 return std::nullopt;
6892 return std::nullopt;
6899 if (
C->containsUndefOrPoisonElement()) {
6900 assert(SafeReplacementConstant &&
"Replacement constant not set");
6907 Constant *OneOrNegOne = ConstantInt::get(
Type, WillIncrement ? 1 : -1,
true);
6910 return std::make_pair(NewPred, NewC);
6922 Value *Op0 =
I.getOperand(0);
6923 Value *Op1 =
I.getOperand(1);
6924 auto *Op1C = dyn_cast<Constant>(Op1);
6928 auto FlippedStrictness =
6930 if (!FlippedStrictness)
6933 return new ICmpInst(FlippedStrictness->first, Op0, FlippedStrictness->second);
6951 I.setName(
I.getName() +
".not");
6962 Value *
A =
I.getOperand(0), *
B =
I.getOperand(1);
6963 assert(
A->getType()->isIntOrIntVectorTy(1) &&
"Bools only");
6969 switch (
I.getPredicate()) {
6978 switch (
I.getPredicate()) {
6988 switch (
I.getPredicate()) {
6997 return BinaryOperator::CreateXor(
A,
B);
7005 return BinaryOperator::CreateAnd(Builder.
CreateNot(
A),
B);
7013 return BinaryOperator::CreateAnd(Builder.
CreateNot(
B),
A);
7021 return BinaryOperator::CreateOr(Builder.
CreateNot(
A),
B);
7029 return BinaryOperator::CreateOr(Builder.
CreateNot(
B),
A);
7085 Value *
LHS = Cmp.getOperand(0), *
RHS = Cmp.getOperand(1);
7090 if (
auto *
I = dyn_cast<Instruction>(V))
7091 I->copyIRFlags(&Cmp);
7092 Module *M = Cmp.getModule();
7102 return createCmpReverse(Pred, V1, V2);
7106 return createCmpReverse(Pred, V1,
RHS);
7110 return createCmpReverse(Pred,
LHS, V2);
7135 Constant *ScalarC =
C->getSplatValue(
true);
7154 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7158 auto UAddOvResultPat = m_ExtractValue<0>(
7160 if (
match(Op0, UAddOvResultPat) &&
7169 UAddOv = cast<ExtractValueInst>(Op0)->getAggregateOperand();
7170 else if (
match(Op1, UAddOvResultPat) &&
7173 UAddOv = cast<ExtractValueInst>(Op1)->getAggregateOperand();
7181 if (!
I.getOperand(0)->getType()->isPointerTy() ||
7183 I.getParent()->getParent(),
7184 I.getOperand(0)->getType()->getPointerAddressSpace())) {
7190 Op->isLaunderOrStripInvariantGroup()) {
7192 Op->getOperand(0),
I.getOperand(1));
7204 if (
I.getType()->isVectorTy())
7226 auto *LHSTy = dyn_cast<FixedVectorType>(
LHS->
getType());
7227 if (!LHSTy || !LHSTy->getElementType()->isIntegerTy())
7230 LHSTy->getNumElements() * LHSTy->getElementType()->getIntegerBitWidth();
7232 if (!
DL.isLegalInteger(NumBits))
7236 auto *ScalarTy = Builder.
getIntNTy(NumBits);
7251 if (
auto *
GEP = dyn_cast<GEPOperator>(Op0))
7255 if (
auto *SI = dyn_cast<SelectInst>(Op0))
7259 if (
auto *
MinMax = dyn_cast<MinMaxIntrinsic>(Op0))
7290 bool IsIntMinPosion =
C->isAllOnesValue();
7302 CxtI, IsIntMinPosion
7305 X, ConstantInt::get(
X->getType(),
SMin + 1)));
7311 CxtI, IsIntMinPosion
7314 X, ConstantInt::get(
X->getType(),
SMin)));
7327 auto CheckUGT1 = [](
const APInt &Divisor) {
return Divisor.ugt(1); };
7342 auto CheckNE0 = [](
const APInt &Shift) {
return !Shift.isZero(); };
7360 bool Changed =
false;
7362 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7369 if (Op0Cplxity < Op1Cplxity) {
7384 if (
Value *V = dyn_castNegVal(SelectTrue)) {
7385 if (V == SelectFalse)
7388 else if (
Value *V = dyn_castNegVal(SelectFalse)) {
7389 if (V == SelectTrue)
7430 if (
SelectInst *SI = dyn_cast<SelectInst>(
I.user_back())) {
7488 if (
I.isCommutative()) {
7489 if (
auto Pair = matchSymmetricPair(
I.getOperand(0),
I.getOperand(1))) {
7513 (Op0->
hasOneUse() || Op1->hasOneUse())) {
7529 assert(Op1->getType()->isPointerTy() &&
"Comparing pointer with non-pointer?");
7558 bool ConsumesOp0, ConsumesOp1;
7561 (ConsumesOp0 || ConsumesOp1)) {
7564 assert(InvOp0 && InvOp1 &&
7565 "Mismatch between isFreeToInvert and getFreelyInverted");
7566 return new ICmpInst(
I.getSwappedPredicate(), InvOp0, InvOp1);
7573 isa<IntegerType>(
X->getType())) {
7578 if (AddI->
getOpcode() == Instruction::Add &&
7579 OptimizeOverflowCheck(Instruction::Add,
false,
X,
Y, *AddI,
7580 Result, Overflow)) {
7598 if ((
I.isUnsigned() ||
I.isEquality()) &&
7601 Y->getType()->getScalarSizeInBits() == 1 &&
7602 (Op0->
hasOneUse() || Op1->hasOneUse())) {
7609 unsigned ShiftOpc = ShiftI->
getOpcode();
7610 if ((ExtOpc == Instruction::ZExt && ShiftOpc == Instruction::LShr) ||
7611 (ExtOpc == Instruction::SExt && ShiftOpc == Instruction::AShr)) {
7640 if (
auto *EVI = dyn_cast<ExtractValueInst>(Op0))
7641 if (
auto *ACXI = dyn_cast<AtomicCmpXchgInst>(EVI->getAggregateOperand()))
7642 if (EVI->getIndices()[0] == 0 && ACXI->getCompareOperand() == Op1 &&
7649 if (
I.getType()->isVectorTy())
7659 return Changed ? &
I :
nullptr;
7673 if (MantissaWidth == -1)
return nullptr;
7677 bool LHSUnsigned = isa<UIToFPInst>(LHSI);
7679 if (
I.isEquality()) {
7681 bool IsExact =
false;
7682 APSInt RHSCvt(IntWidth, LHSUnsigned);
7691 if (*
RHS != RHSRoundInt) {
7711 if ((
int)IntWidth > MantissaWidth) {
7713 int Exp = ilogb(*
RHS);
7716 if (MaxExponent < (
int)IntWidth - !LHSUnsigned)
7722 if (MantissaWidth <= Exp && Exp <= (
int)IntWidth - !LHSUnsigned)
7731 assert(!
RHS->isNaN() &&
"NaN comparison not already folded!");
7734 switch (
I.getPredicate()) {
7824 APSInt RHSInt(IntWidth, LHSUnsigned);
7827 if (!
RHS->isZero()) {
7841 if (
RHS->isNegative())
7847 if (
RHS->isNegative())
7853 if (
RHS->isNegative())
7860 if (!
RHS->isNegative())
7866 if (
RHS->isNegative())
7872 if (
RHS->isNegative())
7878 if (
RHS->isNegative())
7885 if (!
RHS->isNegative())
7939 if (
C->isNegative())
7940 Pred =
I.getSwappedPredicate();
7955 if (!
C->isPosZero()) {
7956 if (!
C->isSmallestNormalized())
7969 switch (
I.getPredicate()) {
7995 switch (
I.getPredicate()) {
8020 assert(!
I.hasNoNaNs() &&
"fcmp should have simplified");
8025 assert(!
I.hasNoNaNs() &&
"fcmp should have simplified");
8039 return replacePredAndOp0(&
I,
I.getPredicate(),
X);
8061 if (!cast<Instruction>(
I.getOperand(0))->hasNoInfs())
8062 I.setHasNoInfs(
false);
8064 switch (
I.getPredicate()) {
8109 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
8114 Pred =
I.getSwappedPredicate();
8123 return new FCmpInst(Pred, Op0, Zero,
"", &
I);
8160 I.getFunction()->getDenormalMode(
8174 bool Changed =
false;
8185 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
8192 assert(OpType == Op1->getType() &&
"fcmp with different-typed operands?");
8216 if (
I.isCommutative()) {
8217 if (
auto Pair = matchSymmetricPair(
I.getOperand(0),
I.getOperand(1))) {
8239 return new FCmpInst(
I.getSwappedPredicate(),
X,
Y,
"", &
I);
8252 if (
SelectInst *SI = dyn_cast<SelectInst>(
I.user_back())) {
8321 Type *IntTy =
X->getType();
8333 case Instruction::Select:
8343 case Instruction::FSub:
8348 case Instruction::PHI:
8352 case Instruction::SIToFP:
8353 case Instruction::UIToFP:
8357 case Instruction::FDiv:
8361 case Instruction::Load:
8362 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(LHSI->
getOperand(0)))
8363 if (
auto *GV = dyn_cast<GlobalVariable>(
GEP->getOperand(0)))
8365 cast<LoadInst>(LHSI),
GEP, GV,
I))
8382 return new FCmpInst(
I.getSwappedPredicate(),
X, NegC,
"", &
I);
8401 X->getType()->getScalarType()->getFltSemantics();
8437 Constant *NewC = ConstantFP::get(
X->getType(), TruncC);
8451 if (
auto *VecTy = dyn_cast<VectorType>(OpType))
8463 Value *CanonLHS =
nullptr, *CanonRHS =
nullptr;
8464 match(Op0, m_Intrinsic<Intrinsic::canonicalize>(
m_Value(CanonLHS)));
8465 match(Op1, m_Intrinsic<Intrinsic::canonicalize>(
m_Value(CanonRHS)));
8468 if (CanonLHS == Op1)
8469 return new FCmpInst(Pred, Op1, Op1,
"", &
I);
8472 if (CanonRHS == Op0)
8473 return new FCmpInst(Pred, Op0, Op0,
"", &
I);
8476 if (CanonLHS && CanonRHS)
8477 return new FCmpInst(Pred, CanonLHS, CanonRHS,
"", &
I);
8480 if (
I.getType()->isVectorTy())
8484 return Changed ? &
I :
nullptr;
amdgpu AMDGPU Register Bank Select
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static Instruction * foldFCmpReciprocalAndZero(FCmpInst &I, Instruction *LHSI, Constant *RHSC)
Fold (C / X) < 0.0 --> X < 0.0 if possible. Swap predicate if necessary.
static Instruction * foldFabsWithFcmpZero(FCmpInst &I, InstCombinerImpl &IC)
Optimize fabs(X) compared with zero.
static Instruction * foldICmpUSubSatOrUAddSatWithConstant(ICmpInst::Predicate Pred, SaturatingInst *II, const APInt &C, InstCombiner::BuilderTy &Builder)
static bool addWithOverflow(APInt &Result, const APInt &In1, const APInt &In2, bool IsSigned=false)
Compute Result = In1+In2, returning true if the result overflowed for this type.
static Value * foldICmpWithLowBitMaskedVal(ICmpInst::Predicate Pred, Value *Op0, Value *Op1, const SimplifyQuery &Q, InstCombiner &IC)
Some comparisons can be simplified.
static Instruction * foldICmpAndXX(ICmpInst &I, const SimplifyQuery &Q, InstCombinerImpl &IC)
static Instruction * foldVectorCmp(CmpInst &Cmp, InstCombiner::BuilderTy &Builder)
static bool isMaskOrZero(const Value *V, bool Not, const SimplifyQuery &Q, unsigned Depth=0)
static Value * createLogicFromTable(const std::bitset< 4 > &Table, Value *Op0, Value *Op1, IRBuilderBase &Builder, bool HasOneUse)
static Instruction * foldICmpOfUAddOv(ICmpInst &I)
static Instruction * foldICmpShlOne(ICmpInst &Cmp, Instruction *Shl, const APInt &C)
Fold icmp (shl 1, Y), C.
static bool isChainSelectCmpBranch(const SelectInst *SI)
Return true when the instruction sequence within a block is select-cmp-br.
static Instruction * foldICmpInvariantGroup(ICmpInst &I)
static Instruction * foldReductionIdiom(ICmpInst &I, InstCombiner::BuilderTy &Builder, const DataLayout &DL)
This function folds patterns produced by lowering of reduce idioms, such as llvm.vector....
static Instruction * canonicalizeICmpBool(ICmpInst &I, InstCombiner::BuilderTy &Builder)
Integer compare with boolean values can always be turned into bitwise ops.
static Instruction * foldFCmpFSubIntoFCmp(FCmpInst &I, Instruction *LHSI, Constant *RHSC, InstCombinerImpl &CI)
static Value * foldICmpOrXorSubChain(ICmpInst &Cmp, BinaryOperator *Or, InstCombiner::BuilderTy &Builder)
Fold icmp eq/ne (or (xor/sub (X1, X2), xor/sub (X3, X4))), 0.
static bool hasBranchUse(ICmpInst &I)
Given an icmp instruction, return true if any use of this comparison is a branch on sign bit comparis...
static APInt getDemandedBitsLHSMask(ICmpInst &I, unsigned BitWidth)
When performing a comparison against a constant, it is possible that not all the bits in the LHS are ...
static Instruction * foldICmpXorXX(ICmpInst &I, const SimplifyQuery &Q, InstCombinerImpl &IC)
static Instruction * processUMulZExtIdiom(ICmpInst &I, Value *MulVal, const APInt *OtherVal, InstCombinerImpl &IC)
Recognize and process idiom involving test for multiplication overflow.
static Instruction * transformToIndexedCompare(GEPOperator *GEPLHS, Value *RHS, ICmpInst::Predicate Cond, const DataLayout &DL, InstCombiner &IC)
Converts (CMP GEPLHS, RHS) if this change would make RHS a constant.
static Instruction * foldSqrtWithFcmpZero(FCmpInst &I, InstCombinerImpl &IC)
Optimize sqrt(X) compared with zero.
static Instruction * foldFCmpFNegCommonOp(FCmpInst &I)
static Instruction * foldICmpOfCmpIntrinsicWithConstant(ICmpInst::Predicate Pred, IntrinsicInst *I, const APInt &C, InstCombiner::BuilderTy &Builder)
static bool canRewriteGEPAsOffset(Value *Start, Value *Base, const DataLayout &DL, SetVector< Value * > &Explored)
Returns true if we can rewrite Start as a GEP with pointer Base and some integer offset.
static Instruction * foldICmpWithHighBitMask(ICmpInst &Cmp, InstCombiner::BuilderTy &Builder)
static ICmpInst * canonicalizeCmpWithConstant(ICmpInst &I)
If we have an icmp le or icmp ge instruction with a constant operand, turn it into the appropriate ic...
static Instruction * foldICmpIntrinsicWithIntrinsic(ICmpInst &Cmp, InstCombiner::BuilderTy &Builder)
Fold an icmp with LLVM intrinsics.
static Instruction * foldICmpPow2Test(ICmpInst &I, InstCombiner::BuilderTy &Builder)
static bool subWithOverflow(APInt &Result, const APInt &In1, const APInt &In2, bool IsSigned=false)
Compute Result = In1-In2, returning true if the result overflowed for this type.
static Instruction * foldICmpXNegX(ICmpInst &I, InstCombiner::BuilderTy &Builder)
static Instruction * processUGT_ADDCST_ADD(ICmpInst &I, Value *A, Value *B, ConstantInt *CI2, ConstantInt *CI1, InstCombinerImpl &IC)
The caller has matched a pattern of the form: I = icmp ugt (add (add A, B), CI2), CI1 If this is of t...
static Value * foldShiftIntoShiftInAnotherHandOfAndInICmp(ICmpInst &I, const SimplifyQuery SQ, InstCombiner::BuilderTy &Builder)
static bool isSignTest(ICmpInst::Predicate &Pred, const APInt &C)
Returns true if the exploded icmp can be expressed as a signed comparison to zero and updates the pre...
static Instruction * foldCtpopPow2Test(ICmpInst &I, IntrinsicInst *CtpopLhs, const APInt &CRhs, InstCombiner::BuilderTy &Builder, const SimplifyQuery &Q)
static void setInsertionPoint(IRBuilder<> &Builder, Value *V, bool Before=true)
static bool isNeutralValue(Instruction::BinaryOps BinaryOp, Value *RHS, bool IsSigned)
static Value * foldICmpWithTruncSignExtendedVal(ICmpInst &I, InstCombiner::BuilderTy &Builder)
Some comparisons can be simplified.
static Value * rewriteGEPAsOffset(Value *Start, Value *Base, const DataLayout &DL, SetVector< Value * > &Explored, InstCombiner &IC)
Returns a re-written value of Start as an indexed GEP using Base as a pointer.
static Instruction * foldICmpOrXX(ICmpInst &I, const SimplifyQuery &Q, InstCombinerImpl &IC)
This file provides internal interfaces used to implement the InstCombine.
This file provides the interface for the instcombine pass implementation.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
mir Rename Register Operands
uint64_t IntrinsicInst * II
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This file implements a set that has insertion order iteration characteristics.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static SymbolRef::Type getType(const Symbol *Sym)
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
static APFloat getSmallestNormalized(const fltSemantics &Sem, bool Negative=false)
Returns the smallest (by magnitude) normalized finite number in the given semantics.
APInt bitcastToAPInt() const
static APFloat getLargest(const fltSemantics &Sem, bool Negative=false)
Returns the largest finite number in the given semantics.
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
FPClassTest classify() const
Return the FPClassTest which will return true for the value.
opStatus roundToIntegral(roundingMode RM)
Class for arbitrary precision integers.
APInt udiv(const APInt &RHS) const
Unsigned division operation.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
APInt zext(unsigned width) const
Zero extend to a new width.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
bool isMinSignedValue() const
Determine if this is the smallest signed value.
uint64_t getZExtValue() const
Get zero extended value.
unsigned getActiveBits() const
Compute the number of active bits in the value.
APInt trunc(unsigned width) const
Truncate to new width.
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
APInt abs() const
Get the absolute value.
unsigned ceilLogBase2() const
bool sgt(const APInt &RHS) const
Signed greater than comparison.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
APInt usub_ov(const APInt &RHS, bool &Overflow) const
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isSignMask() const
Check if the APInt's value is returned by getSignMask.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
static APInt getMinValue(unsigned numBits)
Gets minimum unsigned value of APInt for a specific bit width.
bool isNegative() const
Determine sign of this APInt.
APInt sadd_ov(const APInt &RHS, bool &Overflow) const
bool intersects(const APInt &RHS) const
This operation tests if there are any pairs of corresponding bits between this APInt and RHS that are...
bool eq(const APInt &RHS) const
Equality comparison.
APInt sdiv(const APInt &RHS) const
Signed division function for APInt.
bool sle(const APInt &RHS) const
Signed less or equal comparison.
APInt uadd_ov(const APInt &RHS, bool &Overflow) const
void negate()
Negate this APInt in place.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countl_zero() const
The APInt version of std::countl_zero.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
bool isStrictlyPositive() const
Determine if this APInt Value is positive.
unsigned countl_one() const
Count the number of leading one bits.
unsigned logBase2() const
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
bool isMaxSignedValue() const
Determine if this is the largest signed value.
bool ule(const APInt &RHS) const
Unsigned less or equal comparison.
APInt shl(unsigned shiftAmt) const
Left-shift function.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
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.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
bool sge(const APInt &RHS) const
Signed greater or equal comparison.
APInt ssub_ov(const APInt &RHS, bool &Overflow) const
bool isOne() const
Determine if this is a value of 1.
static APInt getBitsSetFrom(unsigned numBits, unsigned loBit)
Constructs an APInt value that has a contiguous range of bits set.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
unsigned countr_one() const
Count the number of trailing one bits.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
An arbitrary precision integer that knows its signedness.
an instruction to allocate memory on the stack
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Class to represent array types.
LLVM Basic Block Representation.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
BinaryOps getOpcode() const
static BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
static BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
Conditional or Unconditional Branch instruction.
Value * getArgOperand(unsigned i) const
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
This class is the base class for the comparison instructions.
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate getStrictPredicate() const
For example, SGE -> SGT, SLE -> SLT, ULE -> ULT, UGE -> UGT.
bool isEquality() const
Determine if this is an equals/not equals predicate.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ ICMP_ULT
unsigned less than
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
bool isTrueWhenEqual() const
This is just a convenience.
static CmpInst * Create(OtherOps Op, Predicate Pred, Value *S1, Value *S2, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Construct a compare instruction, given the opcode, the predicate and the two operands.
Predicate getNonStrictPredicate() const
For example, SGT -> SGE, SLT -> SLE, ULT -> ULE, UGT -> UGE.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Predicate getPredicate() const
Return the predicate for this instruction.
bool isStrictPredicate() const
Predicate getFlippedStrictnessPredicate() const
For predicate of kind "is X or equal to 0" returns the predicate "is X".
Predicate getFlippedSignednessPredicate()
For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->Failed assert.
bool isIntPredicate() const
static Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getPointerBitCastOrAddrSpaceCast(Constant *C, Type *Ty)
Create a BitCast or AddrSpaceCast for a pointer type depending on the address space.
static Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getNot(Constant *C)
static Constant * getXor(Constant *C1, Constant *C2)
static Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getNeg(Constant *C, bool HasNSW=false)
static Constant * getZero(Type *Ty, bool Negative=false)
This is the shared class of boolean and integer constants.
uint64_t getLimitedValue(uint64_t Limit=~0ULL) const
getLimitedValue - If the value is smaller than the specified limit, return it, otherwise return the l...
static ConstantInt * getTrue(LLVMContext &Context)
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
static ConstantInt * getFalse(LLVMContext &Context)
unsigned getBitWidth() const
getBitWidth - Return the scalar bitwidth of this constant.
const APInt & getValue() const
Return the constant as an APInt value reference.
static ConstantInt * getBool(LLVMContext &Context, bool V)
This class represents a range of values.
ConstantRange add(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an addition of a value in this ran...
std::optional< ConstantRange > exactUnionWith(const ConstantRange &CR) const
Union the two ranges and return the result if it can be represented exactly, otherwise return std::nu...
ConstantRange subtract(const APInt &CI) const
Subtract the specified constant from the endpoints of this constant range.
const APInt * getSingleElement() const
If this set contains a single element, return it, otherwise return null.
ConstantRange difference(const ConstantRange &CR) const
Subtract the specified range from this range (aka relative complement of the sets).
bool isEmptySet() const
Return true if this set contains no members.
static ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)
Produce the exact range such that all values in the returned range satisfy the given predicate with a...
ConstantRange inverse() const
Return a new range that is the logical not of the current set.
std::optional< ConstantRange > exactIntersectWith(const ConstantRange &CR) const
Intersect the two ranges and return the result if it can be represented exactly, otherwise return std...
ConstantRange intersectWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the intersection of this range with another range.
ConstantRange sub(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a subtraction of a value in this r...
static ConstantRange makeExactNoWrapRegion(Instruction::BinaryOps BinOp, const APInt &Other, unsigned NoWrapKind)
Produce the range that contains X if and only if "X BinOp Other" does not wrap.
static Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
This is an important base class in LLVM.
static Constant * getIntegerValue(Type *Ty, const APInt &V)
Return the value for an integer or pointer constant, or a vector thereof, with the given scalar value...
static Constant * replaceUndefsWith(Constant *C, Constant *Replacement)
Try to replace undefined constant C or undefined elements in C with Replacement.
static Constant * getAllOnesValue(Type *Ty)
const APInt & getUniqueInteger() const
If C is a constant integer then return its value, otherwise C must be a vector of constant integers,...
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
unsigned getPointerTypeSizeInBits(Type *) const
Layout pointer size, in bits, based on the type.
IntegerType * getIndexType(LLVMContext &C, unsigned AddressSpace) const
Returns the type of a GEP index in AddressSpace.
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Type * getSmallestLegalIntType(LLVMContext &C, unsigned Width=0) const
Returns the smallest integer type with size at least as big as Width bits.
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
ArrayRef< BranchInst * > conditionsFor(const Value *V) const
Access the list of branches which affect this value.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
This instruction compares its operands according to the predicate given to the constructor.
bool isInBounds() const
Test whether this is an inbounds GEP, as defined by LangRef.html.
Type * getSourceElementType() const
Value * getPointerOperand()
bool hasAllConstantIndices() const
Return true if all of the indices of this GEP are constant integers.
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...
This instruction compares its operands according to the predicate given to the constructor.
static bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
Predicate getSignedPredicate() const
For example, EQ->EQ, SLE->SLE, UGT->SGT, etc.
bool isEquality() const
Return true if this predicate is either EQ or NE.
static bool isEquality(Predicate P)
Return true if this predicate is either EQ or NE.
bool isRelational() const
Return true if the predicate is relational (not EQ or NE).
Predicate getUnsignedPredicate() const
For example, EQ->EQ, SLE->ULE, UGT->UGT, etc.
Common base class shared among various IRBuilders.
CallInst * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with 1 operand which is mangled on its type.
Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
Value * CreateICmpSGT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")
Return a vector value that contains.
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
ConstantInt * getTrue()
Get the constant value for i1 true.
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateNSWAdd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateInBoundsGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="")
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
Value * createIsFPClass(Value *FPNum, unsigned Test)
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Value * CreateCmp(CmpInst::Predicate Pred, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateICmpUGT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
ConstantInt * getFalse()
Get the constant value for i1 false.
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="")
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Value * CreateIsNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg == 0.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
ConstantInt * getInt(const APInt &AI)
Get a constant integer value.
Value * CreateURem(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Instruction * foldICmpShrConstant(ICmpInst &Cmp, BinaryOperator *Shr, const APInt &C)
Fold icmp ({al}shr X, Y), C.
Instruction * FoldOpIntoSelect(Instruction &Op, SelectInst *SI, bool FoldWithMultiUse=false)
Given an instruction with a select as one operand and a constant as the other operand,...
Instruction * foldICmpWithZextOrSext(ICmpInst &ICmp)
Instruction * foldICmpSelectConstant(ICmpInst &Cmp, SelectInst *Select, ConstantInt *C)
Instruction * foldICmpSRemConstant(ICmpInst &Cmp, BinaryOperator *UDiv, const APInt &C)
Instruction * foldICmpBinOpWithConstant(ICmpInst &Cmp, BinaryOperator *BO, const APInt &C)
Fold an icmp with BinaryOp and constant operand: icmp Pred BO, C.
Instruction * foldICmpOrConstant(ICmpInst &Cmp, BinaryOperator *Or, const APInt &C)
Fold icmp (or X, Y), C.
Instruction * foldICmpTruncWithTruncOrExt(ICmpInst &Cmp, const SimplifyQuery &Q)
Fold icmp (trunc nuw/nsw X), (trunc nuw/nsw Y).
Instruction * foldSignBitTest(ICmpInst &I)
Fold equality-comparison between zero and any (maybe truncated) right-shift by one-less-than-bitwidth...
Instruction * foldOpIntoPhi(Instruction &I, PHINode *PN)
Given a binary operator, cast instruction, or select which has a PHI node as operand #0,...
Value * insertRangeTest(Value *V, const APInt &Lo, const APInt &Hi, bool isSigned, bool Inside)
Emit a computation of: (V >= Lo && V < Hi) if Inside is true, otherwise (V < Lo || V >= Hi).
Instruction * foldICmpBinOp(ICmpInst &Cmp, const SimplifyQuery &SQ)
Try to fold icmp (binop), X or icmp X, (binop).
Instruction * foldICmpSubConstant(ICmpInst &Cmp, BinaryOperator *Sub, const APInt &C)
Fold icmp (sub X, Y), C.
Instruction * foldICmpInstWithConstantNotInt(ICmpInst &Cmp)
Handle icmp with constant (but not simple integer constant) RHS.
Instruction * foldICmpWithMinMax(Instruction &I, MinMaxIntrinsic *MinMax, Value *Z, ICmpInst::Predicate Pred)
Fold icmp Pred min|max(X, Y), Z.
Instruction * foldGEPICmp(GEPOperator *GEPLHS, Value *RHS, ICmpInst::Predicate Cond, Instruction &I)
Fold comparisons between a GEP instruction and something else.
Instruction * foldICmpShlConstConst(ICmpInst &I, Value *ShAmt, const APInt &C1, const APInt &C2)
Handle "(icmp eq/ne (shl AP2, A), AP1)" -> (icmp eq/ne A, TrailingZeros(AP1) - TrailingZeros(AP2)).
Value * reassociateShiftAmtsOfTwoSameDirectionShifts(BinaryOperator *Sh0, const SimplifyQuery &SQ, bool AnalyzeForSignBitExtraction=false)
Instruction * foldICmpEqIntrinsicWithConstant(ICmpInst &ICI, IntrinsicInst *II, const APInt &C)
Fold an equality icmp with LLVM intrinsic and constant operand.
Value * foldMultiplicationOverflowCheck(ICmpInst &Cmp)
Fold (-1 u/ x) u< y ((x * y) ?/ x) != y to @llvm.
Instruction * foldICmpWithConstant(ICmpInst &Cmp)
Fold icmp Pred X, C.
CmpInst * canonicalizeICmpPredicate(CmpInst &I)
If we have a comparison with a non-canonical predicate, if we can update all the users,...
Instruction * eraseInstFromFunction(Instruction &I) override
Combiner aware instruction erasure.
Instruction * foldICmpWithZero(ICmpInst &Cmp)
Instruction * foldICmpBinOpEqualityWithConstant(ICmpInst &Cmp, BinaryOperator *BO, const APInt &C)
Fold an icmp equality instruction with binary operator LHS and constant RHS: icmp eq/ne BO,...
Instruction * foldICmpUsingBoolRange(ICmpInst &I)
If one operand of an icmp is effectively a bool (value range of {0,1}), then try to reduce patterns b...
Instruction * foldICmpWithTrunc(ICmpInst &Cmp)
Instruction * foldICmpIntrinsicWithConstant(ICmpInst &ICI, IntrinsicInst *II, const APInt &C)
Fold an icmp with LLVM intrinsic and constant operand: icmp Pred II, C.
bool SimplifyDemandedBits(Instruction *I, unsigned Op, const APInt &DemandedMask, KnownBits &Known, unsigned Depth, const SimplifyQuery &Q) override
This form of SimplifyDemandedBits simplifies the specified instruction operand if possible,...
bool matchThreeWayIntCompare(SelectInst *SI, Value *&LHS, Value *&RHS, ConstantInt *&Less, ConstantInt *&Equal, ConstantInt *&Greater)
Match a select chain which produces one of three values based on whether the LHS is less than,...
Instruction * foldCmpLoadFromIndexedGlobal(LoadInst *LI, GetElementPtrInst *GEP, GlobalVariable *GV, CmpInst &ICI, ConstantInt *AndCst=nullptr)
This is called when we see this pattern: cmp pred (load (gep GV, ...)), cmpcst where GV is a global v...
Instruction * visitFCmpInst(FCmpInst &I)
Instruction * foldICmpUsingKnownBits(ICmpInst &Cmp)
Try to fold the comparison based on range information we can get by checking whether bits are known t...
Instruction * foldICmpDivConstant(ICmpInst &Cmp, BinaryOperator *Div, const APInt &C)
Fold icmp ({su}div X, Y), C.
Instruction * foldIRemByPowerOfTwoToBitTest(ICmpInst &I)
If we have: icmp eq/ne (urem/srem x, y), 0 iff y is a power-of-two, we can replace this with a bit te...
Instruction * foldFCmpIntToFPConst(FCmpInst &I, Instruction *LHSI, Constant *RHSC)
Fold fcmp ([us]itofp x, cst) if possible.
Instruction * foldICmpUDivConstant(ICmpInst &Cmp, BinaryOperator *UDiv, const APInt &C)
Fold icmp (udiv X, Y), C.
Constant * getLosslessTrunc(Constant *C, Type *TruncTy, unsigned ExtOp)
Instruction * foldICmpWithCastOp(ICmpInst &ICmp)
Handle icmp (cast x), (cast or constant).
Instruction * foldICmpTruncConstant(ICmpInst &Cmp, TruncInst *Trunc, const APInt &C)
Fold icmp (trunc X), C.
Instruction * foldICmpAddConstant(ICmpInst &Cmp, BinaryOperator *Add, const APInt &C)
Fold icmp (add X, Y), C.
Instruction * foldICmpMulConstant(ICmpInst &Cmp, BinaryOperator *Mul, const APInt &C)
Fold icmp (mul X, Y), C.
Instruction * tryFoldInstWithCtpopWithNot(Instruction *I)
Instruction * foldICmpXorConstant(ICmpInst &Cmp, BinaryOperator *Xor, const APInt &C)
Fold icmp (xor X, Y), C.
Instruction * foldICmpAddOpConst(Value *X, const APInt &C, ICmpInst::Predicate Pred)
Fold "icmp pred (X+C), X".
Instruction * foldICmpInstWithConstantAllowPoison(ICmpInst &Cmp, const APInt &C)
Try to fold integer comparisons with a constant operand: icmp Pred X, C where X is some kind of instr...
Instruction * foldICmpAndShift(ICmpInst &Cmp, BinaryOperator *And, const APInt &C1, const APInt &C2)
Fold icmp (and (sh X, Y), C2), C1.
Instruction * foldICmpInstWithConstant(ICmpInst &Cmp)
Try to fold integer comparisons with a constant operand: icmp Pred X, C where X is some kind of instr...
Instruction * foldICmpXorShiftConst(ICmpInst &Cmp, BinaryOperator *Xor, const APInt &C)
For power-of-2 C: ((X s>> ShiftC) ^ X) u< C --> (X + C) u< (C << 1) ((X s>> ShiftC) ^ X) u> (C - 1) -...
Instruction * foldICmpShlConstant(ICmpInst &Cmp, BinaryOperator *Shl, const APInt &C)
Fold icmp (shl X, Y), C.
Instruction * foldICmpAndConstant(ICmpInst &Cmp, BinaryOperator *And, const APInt &C)
Fold icmp (and X, Y), C.
Instruction * foldICmpEquality(ICmpInst &Cmp)
bool dominatesAllUses(const Instruction *DI, const Instruction *UI, const BasicBlock *DB) const
True when DB dominates all uses of DI except UI.
bool foldAllocaCmp(AllocaInst *Alloca)
Instruction * foldICmpCommutative(ICmpInst::Predicate Pred, Value *Op0, Value *Op1, ICmpInst &CxtI)
Instruction * visitICmpInst(ICmpInst &I)
Instruction * foldSelectICmp(ICmpInst::Predicate Pred, SelectInst *SI, Value *RHS, const ICmpInst &I)
OverflowResult computeOverflow(Instruction::BinaryOps BinaryOp, bool IsSigned, Value *LHS, Value *RHS, Instruction *CxtI) const
Instruction * foldICmpWithDominatingICmp(ICmpInst &Cmp)
Canonicalize icmp instructions based on dominating conditions.
bool replacedSelectWithOperand(SelectInst *SI, const ICmpInst *Icmp, const unsigned SIOpd)
Try to replace select with select operand SIOpd in SI-ICmp sequence.
Instruction * foldICmpShrConstConst(ICmpInst &I, Value *ShAmt, const APInt &C1, const APInt &C2)
Handle "(icmp eq/ne (ashr/lshr AP2, A), AP1)" -> (icmp eq/ne A, Log2(AP2/AP1)) -> (icmp eq/ne A,...
void freelyInvertAllUsersOf(Value *V, Value *IgnoredUser=nullptr)
Freely adapt every user of V as-if V was changed to !V.
Instruction * foldICmpAndConstConst(ICmpInst &Cmp, BinaryOperator *And, const APInt &C1)
Fold icmp (and X, C2), C1.
Instruction * foldICmpBitCast(ICmpInst &Cmp)
The core instruction combiner logic.
OverflowResult computeOverflowForSignedSub(const Value *LHS, const Value *RHS, const Instruction *CxtI) const
static bool isCanonicalPredicate(CmpInst::Predicate Pred)
Predicate canonicalization reduces the number of patterns that need to be matched by other transforms...
bool isFreeToInvert(Value *V, bool WillInvertAllUses, bool &DoesConsume)
Return true if the specified value is free to invert (apply ~ to).
OverflowResult computeOverflowForUnsignedMul(const Value *LHS, const Value *RHS, const Instruction *CxtI, bool IsNSW=false) const
static unsigned getComplexity(Value *V)
Assign a complexity or rank value to LLVM Values.
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, unsigned Depth=0, const Instruction *CxtI=nullptr)
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
uint64_t MaxArraySizeForCombine
Maximum size of array considered when transforming.
OverflowResult computeOverflowForSignedAdd(const WithCache< const Value * > &LHS, const WithCache< const Value * > &RHS, const Instruction *CxtI) const
static Constant * SubOne(Constant *C)
Subtract one from a Constant.
static std::optional< std::pair< CmpInst::Predicate, Constant * > > getFlippedStrictnessPredicateAndConstant(CmpInst::Predicate Pred, Constant *C)
OverflowResult computeOverflowForUnsignedSub(const Value *LHS, const Value *RHS, const Instruction *CxtI) const
bool canFreelyInvertAllUsersOf(Instruction *V, Value *IgnoredUser)
Given i1 V, can every user of V be freely adapted if V is changed to !V ? InstCombine's freelyInvertA...
void addToWorklist(Instruction *I)
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
OverflowResult computeOverflowForSignedMul(const Value *LHS, const Value *RHS, const Instruction *CxtI) const
void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth, const Instruction *CxtI) const
OverflowResult computeOverflowForUnsignedAdd(const WithCache< const Value * > &LHS, const WithCache< const Value * > &RHS, const Instruction *CxtI) const
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
const SimplifyQuery & getSimplifyQuery() const
unsigned ComputeMaxSignificantBits(const Value *Op, unsigned Depth=0, const Instruction *CxtI=nullptr) const
bool hasNoNaNs() const LLVM_READONLY
Determine whether the no-NaNs flag is set.
bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
bool hasNoInfs() const LLVM_READONLY
Determine whether the no-infs flag is set.
bool isArithmeticShift() const
Return true if this is an arithmetic shift right.
bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
bool isExact() const LLVM_READONLY
Determine whether the exact flag is set.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
An instruction for reading from memory.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This class represents min/max intrinsics.
A Module instance is used to store all the information related to an LLVM module.
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...
Represents a saturating add/sub intrinsic.
This class represents the LLVM 'select' instruction.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, Instruction *MDFrom=nullptr)
A vector that has set insertion semantics.
size_type size() const
Determine the number of elements in the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
bool contains(const key_type &key) const
Check if the SetVector contains the given key.
This instruction constructs a fixed permutation of two input vectors.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
reverse_iterator rbegin()
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Class to represent struct types.
This class represents a truncation of integer types.
bool hasNoSignedWrap() const
Test whether this operation is known to never undergo signed overflow, aka the nsw property.
bool hasNoUnsignedWrap() const
Test whether this operation is known to never undergo unsigned overflow, aka the nuw property.
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getIntegerBitWidth() const
const fltSemantics & getFltSemantics() const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
bool isPointerTy() const
True if this is an instance of PointerType.
static IntegerType * getInt1Ty(LLVMContext &C)
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isPPC_FP128Ty() const
Return true if this is powerpc long double.
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
int getFPMantissaWidth() const
Return the width of the mantissa of this type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isIEEELikeFPTy() const
Return true if this is a well-behaved IEEE-like type, which has a IEEE compatible layout as defined b...
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
A Use represents the edge between a Value definition and its users.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr) const
Accumulate the constant offset this value has compared to a base pointer.
bool hasOneUse() const
Return true if there is exactly one use of this value.
iterator_range< user_iterator > users()
bool hasNUsesOrMore(unsigned N) const
Return true if this value has N uses or more.
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< use_iterator > uses()
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
static VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
constexpr ScalarTy getFixedValue() const
const ParentTy * getParent() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
APInt RoundingUDiv(const APInt &A, const APInt &B, APInt::Rounding RM)
Return A unsign-divided by B, rounded by the given rounding mode.
APInt RoundingSDiv(const APInt &A, const APInt &B, APInt::Rounding RM)
Return A sign-divided by B, rounded by the given rounding mode.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
cst_pred_ty< is_lowbit_mask > m_LowBitMask()
Match an integer or vector with only the low bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power-of-2.
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
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.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
match_combine_or< CastInst_match< OpTy, ZExtInst >, OpTy > m_ZExtOrSelf(const OpTy &Op)
bool match(Val *V, const Pattern &P)
BinOpPred_match< LHS, RHS, is_idiv_op > m_IDiv(const LHS &L, const RHS &R)
Matches integer division operations.
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)
OverflowingBinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWNeg(const ValTy &V)
Matches a 'Neg' as 'sub nsw 0, V'.
cst_pred_ty< is_nonnegative > m_NonNegative()
Match an integer or vector of non-negative values.
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
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.
BinOpPred_match< LHS, RHS, is_logical_shift_op > m_LogicalShift(const LHS &L, const RHS &R)
Matches logical shift operations.
match_combine_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)
Combine two pattern matchers matching L && R.
MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > m_SMin(const LHS &L, const RHS &R)
m_Intrinsic_Ty< Opnd0 >::Ty m_Sqrt(const Opnd0 &Op0)
BinaryOp_match< LHS, RHS, Instruction::Xor, true > m_c_Xor(const LHS &L, const RHS &R)
Matches an Xor with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::FAdd > m_FAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
cst_pred_ty< is_zero_int > m_ZeroInt()
Match an integer 0 or a vector with all elements equal to 0.
apint_match m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
NoWrapTrunc_match< OpTy, TruncInst::NoSignedWrap > m_NSWTrunc(const OpTy &Op)
Matches trunc nsw.
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate > m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)
OneUse_match< T > m_OneUse(const T &SubPattern)
BinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub > m_Neg(const ValTy &V)
Matches a 'Neg' as 'sub 0, V'.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
match_combine_and< class_match< Constant >, match_unless< constantexpr_match > > m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
CastInst_match< OpTy, FPExtInst > m_FPExt(const OpTy &Op)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWMul(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::UDiv > m_UDiv(const LHS &L, const RHS &R)
cst_pred_ty< is_negated_power2_or_zero > m_NegatedPower2OrZero()
Match a integer or vector negated power-of-2.
NoWrapTrunc_match< OpTy, TruncInst::NoUnsignedWrap > m_NUWTrunc(const OpTy &Op)
Matches trunc nuw.
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate, true > m_c_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
cst_pred_ty< custom_checkfn< APInt > > m_CheckedInt(function_ref< bool(const APInt &)> CheckFn)
Match an integer or vector where CheckFn(ele) for each element is true.
cst_pred_ty< is_lowbit_mask_or_zero > m_LowBitMaskOrZero()
Match an integer or vector with only the low bit(s) set.
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, UIToFPInst > m_UIToFP(const OpTy &Op)
CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
Signum_match< Val_t > m_Signum(const Val_t &V)
Matches a signum pattern.
CastInst_match< OpTy, SIToFPInst > m_SIToFP(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > > m_ZExtOrSExt(const OpTy &Op)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
cstfp_pred_ty< is_pos_zero_fp > m_PosZeroFP()
Match a floating-point positive zero.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
UAddWithOverflow_match< LHS_t, RHS_t, Sum_t > m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S)
Match an icmp instruction checking for unsigned overflow on addition.
m_Intrinsic_Ty< Opnd0 >::Ty m_VecReverse(const Opnd0 &Op0)
BinOpPred_match< LHS, RHS, is_irem_op > m_IRem(const LHS &L, const RHS &R)
Matches integer remainder operations.
apfloat_match m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
match_combine_or< match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty >, MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > >, match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty >, MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > > > m_MaxOrMin(const LHS &L, const RHS &R)
CastInst_match< OpTy, FPTruncInst > m_FPTrunc(const OpTy &Op)
auto m_Undef()
Match an arbitrary undef constant.
BinaryOp_match< cst_pred_ty< is_all_ones >, ValTy, Instruction::Xor, true > m_Not(const ValTy &V)
Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
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.
ElementWiseBitCast_match< OpTy > m_ElementWiseBitCast(const OpTy &Op)
m_Intrinsic_Ty< Opnd0 >::Ty m_FAbs(const Opnd0 &Op0)
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.
CastOperator_match< OpTy, Instruction::PtrToInt > m_PtrToInt(const OpTy &Op)
Matches PtrToInt.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
match_unless< Ty > m_Unless(const Ty &M)
Match if the inner matcher does NOT match.
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
cst_pred_ty< icmp_pred_with_threshold > m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold)
Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.
This is an optimization pass for GlobalISel generic memory operations.
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
@ NeverOverflows
Never overflows.
@ AlwaysOverflowsHigh
Always overflows in the direction of signed/unsigned max value.
@ AlwaysOverflowsLow
Always overflows in the direction of signed/unsigned min value.
@ MayOverflow
May or may not overflow.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS, bool &TrueIfSigned)
Given an exploded icmp instruction, return true if the comparison only checks the sign bit.
bool isKnownNeverInfinity(const Value *V, unsigned Depth, const SimplifyQuery &SQ)
Return true if the floating-point scalar value is not an infinity or if the floating-point vector val...
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Instruction *I=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
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...
bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return true if the given value is known to have exactly one bit set when defined.
ConstantRange computeConstantRange(const Value *V, bool ForSigned, bool UseInstrInfo=true, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Determine the possible constant range of an integer or vector of integer value.
Constant * ConstantFoldExtractValueInstruction(Constant *Agg, ArrayRef< unsigned > Idxs)
Attempt to constant fold an extractvalue instruction with the specified operands and indices.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for an Add, fold the result or return null.
bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)
Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
Value * emitGEPOffset(IRBuilderBase *Builder, const DataLayout &DL, User *GEP, bool NoAssumptions=false)
Given a getelementptr instruction/constantexpr, emit the code necessary to compute the offset from th...
constexpr unsigned MaxAnalysisRecursionDepth
Constant * ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op, const DataLayout &DL)
Attempt to constant fold a unary operation with the specified operand.
SelectPatternFlavor
Specific patterns of select instructions we can match.
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures, unsigned MaxUsesToExplore=0)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)
Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind and providing the out param...
bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
Value * simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an ICmpInst, fold the result or return null.
bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
bool isKnownNegative(const Value *V, const SimplifyQuery &DL, unsigned Depth=0)
Returns true if the given value is known be negative (i.e.
@ UMin
Unsigned integer min implemented in terms of select(cmp()).
@ Or
Bitwise or logical OR of integers.
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ SMax
Signed integer max implemented in terms of select(cmp()).
@ And
Bitwise or logical AND of integers.
@ SMin
Signed integer min implemented in terms of select(cmp()).
@ UMax
Unsigned integer max implemented in terms of select(cmp()).
void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
DWARFExpression::Operation Op
constexpr unsigned BitWidth
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
bool decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate &Pred, Value *&X, APInt &Mask, bool LookThroughTrunc=true)
Decompose an icmp into the form ((X & Mask) pred 0) if possible.
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
bool isKnownNeverNaN(const Value *V, unsigned Depth, const SimplifyQuery &SQ)
Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...
bool isKnownPositive(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the given value is known be positive (i.e.
Value * simplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q)
Given operands for an FCmpInst, fold the result or return null.
bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the give value is known to be non-negative.
std::optional< bool > isImpliedCondition(const Value *LHS, const Value *RHS, const DataLayout &DL, bool LHSIsTrue=true, unsigned Depth=0)
Return true if RHS is known to be implied true by LHS.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static constexpr roundingMode rmNearestTiesToEven
static constexpr roundingMode rmTowardZero
This callback is used in conjunction with PointerMayBeCaptured.
Represent subnormal handling kind for floating point instruction inputs and outputs.
@ PreserveSign
The sign of a flushed-to-zero number is preserved in the sign of 0.
@ PositiveZero
Denormals are flushed to positive zero.
static constexpr DenormalMode getIEEE()
bool isNonNegative() const
Returns true if this value is known to be non-negative.
bool isZero() const
Returns true if value is all zero.
unsigned countMinTrailingZeros() const
Returns the minimum number of trailing zero bits.
unsigned countMaxTrailingZeros() const
Returns the maximum number of trailing zero bits possible.
APInt getSignedMaxValue() const
Return the maximal signed value possible given these KnownBits.
unsigned countMaxPopulation() const
Returns the maximum number of bits that could be one.
unsigned getBitWidth() const
Get the bit width of this value.
bool isConstant() const
Returns true if we know the value of all bits.
unsigned countMinLeadingZeros() const
Returns the minimum number of leading zero bits.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
APInt getMinValue() const
Return the minimal unsigned value possible given these KnownBits.
bool isNegative() const
Returns true if this value is known to be negative.
unsigned countMinPopulation() const
Returns the number of bits known to be one.
APInt getSignedMinValue() const
Return the minimal signed value possible given these KnownBits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
SelectPatternFlavor Flavor
static bool isMinOrMax(SelectPatternFlavor SPF)
When implementing this min/max pattern as fcmp; select, does the fcmp have to be ordered?
SimplifyQuery getWithInstruction(const Instruction *I) const
SimplifyQuery getWithoutDomCondCache() const
A MapVector that performs no allocations if smaller than a certain size.