33using namespace PatternMatch;
35#define DEBUG_TYPE "instcombine"
44 const APInt &In2,
bool IsSigned =
false) {
47 Result = In1.
sadd_ov(In2, Overflow);
49 Result = In1.
uadd_ov(In2, Overflow);
57 const APInt &In2,
bool IsSigned =
false) {
60 Result = In1.
ssub_ov(In2, Overflow);
62 Result = In1.
usub_ov(In2, Overflow);
70 for (
auto *U :
I.users())
71 if (isa<BranchInst>(U))
81 if (!ICmpInst::isSigned(Pred))
88 if (Pred == ICmpInst::ICMP_SLT) {
89 Pred = ICmpInst::ICMP_SLE;
92 }
else if (
C.isAllOnes()) {
93 if (Pred == ICmpInst::ICMP_SGT) {
94 Pred = ICmpInst::ICMP_SGE;
119 if (!isa<ConstantArray>(
Init) && !isa<ConstantDataArray>(
Init))
122 uint64_t ArrayElementCount =
Init->getType()->getArrayNumElements();
131 if (
GEP->getNumOperands() < 3 || !isa<ConstantInt>(
GEP->getOperand(1)) ||
132 !cast<ConstantInt>(
GEP->getOperand(1))->isZero() ||
133 isa<Constant>(
GEP->getOperand(2)))
141 Type *EltTy =
Init->getType()->getArrayElementType();
142 for (
unsigned i = 3, e =
GEP->getNumOperands(); i != e; ++i) {
148 if ((
unsigned)IdxVal != IdxVal)
151 if (
StructType *STy = dyn_cast<StructType>(EltTy))
152 EltTy = STy->getElementType(IdxVal);
153 else if (
ArrayType *ATy = dyn_cast<ArrayType>(EltTy)) {
154 if (IdxVal >= ATy->getNumElements())
156 EltTy = ATy->getElementType();
164 enum { Overdefined = -3, Undefined = -2 };
173 int FirstTrueElement = Undefined, SecondTrueElement = Undefined;
177 int FirstFalseElement = Undefined, SecondFalseElement = Undefined;
185 int TrueRangeEnd = Undefined, FalseRangeEnd = Undefined;
194 for (
unsigned i = 0, e = ArrayElementCount; i != e; ++i) {
200 if (!LaterIndices.
empty()) {
215 CompareRHS,
DL, &
TLI);
220 if (isa<UndefValue>(
C)) {
223 if (TrueRangeEnd == (
int)i - 1)
225 if (FalseRangeEnd == (
int)i - 1)
232 if (!isa<ConstantInt>(
C))
237 bool IsTrueForElt = !cast<ConstantInt>(
C)->isZero();
242 if (FirstTrueElement == Undefined)
243 FirstTrueElement = TrueRangeEnd = i;
246 if (SecondTrueElement == Undefined)
247 SecondTrueElement = i;
249 SecondTrueElement = Overdefined;
252 if (TrueRangeEnd == (
int)i - 1)
255 TrueRangeEnd = Overdefined;
259 if (FirstFalseElement == Undefined)
260 FirstFalseElement = FalseRangeEnd = i;
263 if (SecondFalseElement == Undefined)
264 SecondFalseElement = i;
266 SecondFalseElement = Overdefined;
269 if (FalseRangeEnd == (
int)i - 1)
272 FalseRangeEnd = Overdefined;
277 if (i < 64 && IsTrueForElt)
278 MagicBitvector |= 1ULL << i;
283 if ((i & 8) == 0 && i >= 64 && SecondTrueElement == Overdefined &&
284 SecondFalseElement == Overdefined && TrueRangeEnd == Overdefined &&
285 FalseRangeEnd == Overdefined)
296 if (!
GEP->isInBounds()) {
299 if (
Idx->getType()->getPrimitiveSizeInBits().getFixedValue() > OffsetSize)
310 unsigned ElementSize =
323 if (SecondTrueElement != Overdefined) {
326 if (FirstTrueElement == Undefined)
329 Value *FirstTrueIdx = ConstantInt::get(
Idx->getType(), FirstTrueElement);
332 if (SecondTrueElement == Undefined)
337 Value *SecondTrueIdx = ConstantInt::get(
Idx->getType(), SecondTrueElement);
339 return BinaryOperator::CreateOr(C1, C2);
344 if (SecondFalseElement != Overdefined) {
347 if (FirstFalseElement == Undefined)
350 Value *FirstFalseIdx = ConstantInt::get(
Idx->getType(), FirstFalseElement);
353 if (SecondFalseElement == Undefined)
358 Value *SecondFalseIdx =
359 ConstantInt::get(
Idx->getType(), SecondFalseElement);
361 return BinaryOperator::CreateAnd(C1, C2);
366 if (TrueRangeEnd != Overdefined) {
367 assert(TrueRangeEnd != FirstTrueElement &&
"Should emit single compare");
371 if (FirstTrueElement) {
372 Value *Offs = ConstantInt::get(
Idx->getType(), -FirstTrueElement);
377 ConstantInt::get(
Idx->getType(), TrueRangeEnd - FirstTrueElement + 1);
382 if (FalseRangeEnd != Overdefined) {
383 assert(FalseRangeEnd != FirstFalseElement &&
"Should emit single compare");
386 if (FirstFalseElement) {
387 Value *Offs = ConstantInt::get(
Idx->getType(), -FirstFalseElement);
392 ConstantInt::get(
Idx->getType(), FalseRangeEnd - FirstFalseElement);
405 if (ArrayElementCount <= Idx->
getType()->getIntegerBitWidth())
439 while (!WorkList.
empty()) {
442 while (!WorkList.
empty()) {
443 if (Explored.
size() >= 100)
453 if (!isa<GetElementPtrInst>(V) && !isa<PHINode>(V))
458 if (
auto *
GEP = dyn_cast<GEPOperator>(V)) {
460 auto IsNonConst = [](
Value *V) {
return !isa<ConstantInt>(V); };
461 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",
587 if (isa<PHINode>(Val))
594 for (
Value *Val : Explored) {
599 if (
auto *
PHI = dyn_cast<PHINode>(Val)) {
601 for (
unsigned I = 0, E =
PHI->getNumIncomingValues();
I < E; ++
I) {
602 Value *NewIncoming =
PHI->getIncomingValue(
I);
604 auto It = NewInsts.
find(NewIncoming);
605 if (It != NewInsts.
end())
606 NewIncoming = It->second;
613 for (
Value *Val : Explored) {
620 Val->getName() +
".ptr", NW);
627 return NewInsts[Start];
689 if (!isa<GetElementPtrInst>(
RHS))
721 isa<Constant>(
RHS) && cast<Constant>(
RHS)->isNullValue() &&
743 auto EC = cast<VectorType>(GEPLHS->
getType())->getElementCount();
748 cast<Constant>(
RHS),
Base->getType()));
752 if (PtrBase != GEPRHS->getOperand(0)) {
753 bool IndicesTheSame =
756 GEPRHS->getPointerOperand()->getType() &&
760 if (GEPLHS->
getOperand(i) != GEPRHS->getOperand(i)) {
761 IndicesTheSame =
false;
774 if (GEPLHS->
isInBounds() && GEPRHS->isInBounds() &&
776 (GEPRHS->hasAllConstantIndices() || GEPRHS->hasOneUse()) &&
780 Value *LOffset = EmitGEPOffset(GEPLHS);
781 Value *ROffset = EmitGEPOffset(GEPRHS);
788 if (LHSIndexTy != RHSIndexTy) {
811 unsigned NumDifferences = 0;
812 unsigned DiffOperand = 0;
813 for (
unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i)
814 if (GEPLHS->
getOperand(i) != GEPRHS->getOperand(i)) {
816 Type *RHSType = GEPRHS->getOperand(i)->getType();
827 if (NumDifferences++)
break;
831 if (NumDifferences == 0)
835 else if (NumDifferences == 1 && CanFold(NW)) {
837 Value *RHSV = GEPRHS->getOperand(DiffOperand);
838 return NewICmp(NW, LHSV, RHSV);
844 Value *L = EmitGEPOffset(GEPLHS,
true);
845 Value *R = EmitGEPOffset(GEPRHS,
true);
846 return NewICmp(NW, L, R);
872 bool Captured =
false;
877 CmpCaptureTracker(
AllocaInst *Alloca) : Alloca(Alloca) {}
879 void tooManyUses()
override { Captured =
true; }
881 bool captured(
const Use *U)
override {
882 auto *ICmp = dyn_cast<ICmpInst>(U->getUser());
890 ICmps[ICmp] |= 1u << U->getOperandNo();
899 CmpCaptureTracker Tracker(Alloca);
901 if (Tracker.Captured)
904 bool Changed =
false;
905 for (
auto [ICmp,
Operands] : Tracker.ICmps) {
911 auto *Res = ConstantInt::get(
937 assert(!!
C &&
"C should not be zero!");
943 Constant *R = ConstantInt::get(
X->getType(),
953 ConstantInt::get(
X->getType(), -
C));
965 ConstantInt::get(
X->getType(),
SMax -
C));
976 ConstantInt::get(
X->getType(),
SMax - (
C - 1)));
985 assert(
I.isEquality() &&
"Cannot fold icmp gt/lt");
988 if (
I.getPredicate() ==
I.ICMP_NE)
997 bool IsAShr = isa<AShrOperator>(
I.getOperand(0));
1009 return getICmp(
I.ICMP_UGT,
A,
1010 ConstantInt::get(
A->getType(), AP2.
logBase2()));
1022 if (IsAShr && AP1 == AP2.
ashr(Shift)) {
1026 return getICmp(
I.ICMP_UGE,
A, ConstantInt::get(
A->getType(), Shift));
1027 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1028 }
else if (AP1 == AP2.
lshr(Shift)) {
1029 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1035 auto *TorF = ConstantInt::get(
I.getType(),
I.getPredicate() ==
I.ICMP_NE);
1044 assert(
I.isEquality() &&
"Cannot fold icmp gt/lt");
1047 if (
I.getPredicate() ==
I.ICMP_NE)
1058 if (!AP1 && AP2TrailingZeros != 0)
1061 ConstantInt::get(
A->getType(), AP2.
getBitWidth() - AP2TrailingZeros));
1069 if (Shift > 0 && AP2.
shl(Shift) == AP1)
1070 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1074 auto *TorF = ConstantInt::get(
I.getType(),
I.getPredicate() ==
I.ICMP_NE);
1095 Instruction *AddWithCst = cast<Instruction>(
I.getOperand(0));
1103 if (NewWidth != 7 && NewWidth != 15 && NewWidth != 31)
1127 if (U == AddWithCst)
1145 I.getModule(), Intrinsic::sadd_with_overflow, NewType);
1174 if (!
I.isEquality())
1205 APInt(XBitWidth, XBitWidth - 1))))
1207 }
else if (isa<BinaryOperator>(Val) &&
1232 return new ICmpInst(Pred,
B, Cmp.getOperand(1));
1234 return new ICmpInst(Pred,
A, Cmp.getOperand(1));
1251 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1263 return new ICmpInst(Pred,
Y, Cmp.getOperand(1));
1269 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1271 auto *BO0 = cast<OverflowingBinaryOperator>(Cmp.getOperand(0));
1272 if (BO0->hasNoUnsignedWrap() || BO0->hasNoSignedWrap()) {
1280 return new ICmpInst(Pred,
Y, Cmp.getOperand(1));
1285 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1317 Value *Op0 = Cmp.getOperand(0), *Op1 = Cmp.getOperand(1);
1330 if (
auto *Phi = dyn_cast<PHINode>(Op0))
1331 if (
all_of(Phi->operands(), [](
Value *V) { return isa<Constant>(V); })) {
1333 for (
Value *V : Phi->incoming_values()) {
1342 for (
auto [V, Pred] :
zip(Ops, Phi->blocks()))
1357 Value *
X = Cmp.getOperand(0), *
Y = Cmp.getOperand(1);
1390 if (Cmp.isEquality() || (IsSignBit &&
hasBranchUse(Cmp)))
1395 if (Cmp.hasOneUse() &&
1409 if (!
match(BI->getCondition(),
1415 if (
auto *V = handleDomCond(DomPred, DomC))
1435 Type *SrcTy =
X->getType();
1441 if (shouldChangeType(Trunc->
getType(), SrcTy)) {
1443 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy,
C.sext(SrcBits)));
1445 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy,
C.zext(SrcBits)));
1448 if (
C.isOne() &&
C.getBitWidth() > 1) {
1453 ConstantInt::get(V->getType(), 1));
1463 auto NewPred = (Pred == Cmp.ICMP_EQ) ? Cmp.ICMP_UGE : Cmp.ICMP_ULT;
1464 return new ICmpInst(NewPred,
Y, ConstantInt::get(SrcTy, DstBits));
1469 return new ICmpInst(Pred,
Y, ConstantInt::get(SrcTy,
C.logBase2()));
1472 if (Cmp.isEquality() && Trunc->
hasOneUse()) {
1475 if (!SrcTy->
isVectorTy() && shouldChangeType(DstBits, SrcBits)) {
1479 Constant *WideC = ConstantInt::get(SrcTy,
C.zext(SrcBits));
1488 if ((Known.
Zero | Known.
One).countl_one() >= SrcBits - DstBits) {
1490 APInt NewRHS =
C.zext(SrcBits);
1492 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy, NewRHS));
1500 const APInt *ShAmtC;
1521 bool YIsSExt =
false;
1524 unsigned NoWrapFlags = cast<TruncInst>(Cmp.getOperand(0))->getNoWrapKind() &
1525 cast<TruncInst>(Cmp.getOperand(1))->getNoWrapKind();
1526 if (Cmp.isSigned()) {
1537 if (
X->getType() !=
Y->getType() &&
1538 (!Cmp.getOperand(0)->hasOneUse() || !Cmp.getOperand(1)->hasOneUse()))
1540 if (!isDesirableIntType(
X->getType()->getScalarSizeInBits()) &&
1541 isDesirableIntType(
Y->getType()->getScalarSizeInBits())) {
1543 Pred = Cmp.getSwappedPredicate(Pred);
1548 else if (!Cmp.isSigned() &&
1558 isa<SExtInst>(Cmp.getOperand(0)) || isa<SExtInst>(Cmp.getOperand(1));
1562 Type *TruncTy = Cmp.getOperand(0)->getType();
1567 if (isDesirableIntType(TruncBits) &&
1568 !isDesirableIntType(
X->getType()->getScalarSizeInBits()))
1591 bool TrueIfSigned =
false;
1608 if (
Xor->hasOneUse()) {
1610 if (!Cmp.isEquality() && XorC->
isSignMask()) {
1611 Pred = Cmp.getFlippedSignednessPredicate();
1612 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(),
C ^ *XorC));
1617 Pred = Cmp.getFlippedSignednessPredicate();
1618 Pred = Cmp.getSwappedPredicate(Pred);
1619 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(),
C ^ *XorC));
1626 if (*XorC == ~
C && (
C + 1).isPowerOf2())
1629 if (*XorC ==
C && (
C + 1).isPowerOf2())
1634 if (*XorC == -
C &&
C.isPowerOf2())
1636 ConstantInt::get(
X->getType(), ~
C));
1638 if (*XorC ==
C && (-
C).isPowerOf2())
1640 ConstantInt::get(
X->getType(), ~
C));
1662 const APInt *ShiftC;
1667 Type *XType =
X->getType();
1673 return new ICmpInst(Pred,
Add, ConstantInt::get(XType, Bound));
1682 if (!Shift || !Shift->
isShift())
1690 unsigned ShiftOpcode = Shift->
getOpcode();
1691 bool IsShl = ShiftOpcode == Instruction::Shl;
1694 APInt NewAndCst, NewCmpCst;
1695 bool AnyCmpCstBitsShiftedOut;
1696 if (ShiftOpcode == Instruction::Shl) {
1704 NewCmpCst = C1.
lshr(*C3);
1705 NewAndCst = C2.
lshr(*C3);
1706 AnyCmpCstBitsShiftedOut = NewCmpCst.
shl(*C3) != C1;
1707 }
else if (ShiftOpcode == Instruction::LShr) {
1712 NewCmpCst = C1.
shl(*C3);
1713 NewAndCst = C2.
shl(*C3);
1714 AnyCmpCstBitsShiftedOut = NewCmpCst.
lshr(*C3) != C1;
1720 assert(ShiftOpcode == Instruction::AShr &&
"Unknown shift opcode");
1721 NewCmpCst = C1.
shl(*C3);
1722 NewAndCst = C2.
shl(*C3);
1723 AnyCmpCstBitsShiftedOut = NewCmpCst.
ashr(*C3) != C1;
1724 if (NewAndCst.
ashr(*C3) != C2)
1728 if (AnyCmpCstBitsShiftedOut) {
1738 Shift->
getOperand(0), ConstantInt::get(
And->getType(), NewAndCst));
1739 return new ICmpInst(Cmp.getPredicate(),
1740 NewAnd, ConstantInt::get(
And->getType(), NewCmpCst));
1757 return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
1772 if (isICMP_NE && Cmp.getType()->isVectorTy() && C1.
isZero() &&
1774 return new TruncInst(
And->getOperand(0), Cmp.getType());
1785 ConstantInt::get(
X->getType(), ~*C2));
1790 ConstantInt::get(
X->getType(), -*C2));
1793 if (!
And->hasOneUse())
1796 if (Cmp.isEquality() && C1.
isZero()) {
1814 Constant *NegBOC = ConstantInt::get(
And->getType(), -NewC2);
1816 return new ICmpInst(NewPred,
X, NegBOC);
1834 if (!Cmp.getType()->isVectorTy()) {
1835 Type *WideType = W->getType();
1837 Constant *ZextC1 = ConstantInt::get(WideType, C1.
zext(WideScalarBits));
1838 Constant *ZextC2 = ConstantInt::get(WideType, C2->
zext(WideScalarBits));
1840 return new ICmpInst(Cmp.getPredicate(), NewAnd, ZextC1);
1851 if (!Cmp.isSigned() && C1.
isZero() &&
And->getOperand(0)->hasOneUse() &&
1853 Constant *One = cast<Constant>(
And->getOperand(1));
1858 unsigned UsesRemoved = 0;
1859 if (
And->hasOneUse())
1861 if (
Or->hasOneUse())
1868 if (UsesRemoved >= RequireUsesRemoved) {
1872 One,
Or->getName());
1874 return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
1884 if (!Cmp.getParent()->getParent()->hasFnAttribute(
1885 Attribute::NoImplicitFloat) &&
1888 Type *FPType = V->getType()->getScalarType();
1889 if (FPType->isIEEELikeFPTy() && C1 == *C2) {
1890 APInt ExponentMask =
1892 if (C1 == ExponentMask) {
1925 Constant *MinSignedC = ConstantInt::get(
1929 return new ICmpInst(NewPred,
X, MinSignedC);
1938 if (
auto *C2 = dyn_cast<ConstantInt>(
Y))
1939 if (
auto *LI = dyn_cast<LoadInst>(
X))
1940 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(LI->getOperand(0)))
1941 if (
auto *GV = dyn_cast<GlobalVariable>(
GEP->getOperand(0)))
1946 if (!Cmp.isEquality())
1952 if (Cmp.getOperand(1) ==
Y &&
C.isNegatedPowerOf2()) {
1955 return new ICmpInst(NewPred,
X,
SubOne(cast<Constant>(Cmp.getOperand(1))));
1968 assert(Cmp.isEquality() &&
"Not expecting non-equality predicates");
1970 const APInt *TC, *FC;
1987 X->getType()->isIntOrIntVectorTy(1) && (
C.isZero() ||
C.isOne())) {
1993 return BinaryOperator::CreateAnd(TruncY,
X);
2011 const APInt *Addend, *Msk;
2014 Msk->
isMask() &&
C.ule(*Msk)) {
2015 APInt NewComperand = (
C - *Addend) & *Msk;
2041 while (!WorkList.
empty()) {
2042 auto MatchOrOperatorArgument = [&](
Value *OrOperatorArgument) {
2045 if (
match(OrOperatorArgument,
2051 if (
match(OrOperatorArgument,
2061 Value *OrOperatorLhs, *OrOperatorRhs;
2063 if (!
match(CurrentValue,
2068 MatchOrOperatorArgument(OrOperatorRhs);
2069 MatchOrOperatorArgument(OrOperatorLhs);
2075 CmpValues.
rbegin()->second);
2077 for (
auto It = CmpValues.
rbegin() + 1; It != CmpValues.
rend(); ++It) {
2079 LhsCmp = Builder.
CreateBinOp(BOpc, LhsCmp, RhsCmp);
2095 ConstantInt::get(V->getType(), 1));
2098 Value *OrOp0 =
Or->getOperand(0), *OrOp1 =
Or->getOperand(1);
2103 cast<PossiblyDisjointInst>(
Or)->isDisjoint()) {
2106 return new ICmpInst(Pred, OrOp0, NewC);
2110 if (
match(OrOp1,
m_APInt(MaskC)) && Cmp.isEquality()) {
2111 if (*MaskC ==
C && (
C + 1).isPowerOf2()) {
2116 return new ICmpInst(Pred, OrOp0, OrOp1);
2123 if (
Or->hasOneUse()) {
2125 Constant *NewC = ConstantInt::get(
Or->getType(),
C ^ (*MaskC));
2137 Constant *NewC = ConstantInt::get(
X->getType(), TrueIfSigned ? 1 : 0);
2165 if (!Cmp.isEquality() || !
C.isZero() || !
Or->hasOneUse())
2197 if (Cmp.isEquality() &&
C.isZero() &&
X ==
Mul->getOperand(1) &&
2198 (
Mul->hasNoUnsignedWrap() ||
Mul->hasNoSignedWrap()))
2220 if (Cmp.isEquality()) {
2222 if (
Mul->hasNoSignedWrap() &&
C.srem(*MulC).isZero()) {
2223 Constant *NewC = ConstantInt::get(MulTy,
C.sdiv(*MulC));
2231 if (
C.urem(*MulC).isZero()) {
2234 if ((*MulC & 1).isOne() ||
Mul->hasNoUnsignedWrap()) {
2235 Constant *NewC = ConstantInt::get(MulTy,
C.udiv(*MulC));
2248 if (
C.isMinSignedValue() && MulC->
isAllOnes())
2254 NewC = ConstantInt::get(
2258 "Unexpected predicate");
2259 NewC = ConstantInt::get(
2264 NewC = ConstantInt::get(
2268 "Unexpected predicate");
2269 NewC = ConstantInt::get(
2274 return NewC ?
new ICmpInst(Pred,
X, NewC) :
nullptr;
2286 unsigned TypeBits =
C.getBitWidth();
2288 if (Cmp.isUnsigned()) {
2308 return new ICmpInst(Pred,
Y, ConstantInt::get(ShiftType, CLog2));
2309 }
else if (Cmp.isSigned() && C2->
isOne()) {
2310 Constant *BitWidthMinusOne = ConstantInt::get(ShiftType, TypeBits - 1);
2331 const APInt *ShiftVal;
2361 const APInt *ShiftAmt;
2367 unsigned TypeBits =
C.getBitWidth();
2368 if (ShiftAmt->
uge(TypeBits))
2380 APInt ShiftedC =
C.ashr(*ShiftAmt);
2381 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2384 C.ashr(*ShiftAmt).shl(*ShiftAmt) ==
C) {
2385 APInt ShiftedC =
C.ashr(*ShiftAmt);
2386 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2393 assert(!
C.isMinSignedValue() &&
"Unexpected icmp slt");
2394 APInt ShiftedC = (
C - 1).ashr(*ShiftAmt) + 1;
2395 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2405 APInt ShiftedC =
C.lshr(*ShiftAmt);
2406 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2409 C.lshr(*ShiftAmt).shl(*ShiftAmt) ==
C) {
2410 APInt ShiftedC =
C.lshr(*ShiftAmt);
2411 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2418 assert(
C.ugt(0) &&
"ult 0 should have been eliminated");
2419 APInt ShiftedC = (
C - 1).lshr(*ShiftAmt) + 1;
2420 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2424 if (Cmp.isEquality() && Shl->
hasOneUse()) {
2430 Constant *LShrC = ConstantInt::get(ShType,
C.lshr(*ShiftAmt));
2435 bool TrueIfSigned =
false;
2447 if (Cmp.isUnsigned() && Shl->
hasOneUse()) {
2449 if ((
C + 1).isPowerOf2() &&
2457 if (
C.isPowerOf2() &&
2486 if (
auto FlippedStrictness =
2488 Pred, ConstantInt::get(ShType->
getContext(),
C))) {
2489 CmpPred = FlippedStrictness->first;
2490 RHSC = cast<ConstantInt>(FlippedStrictness->second)->getValue();
2497 ConstantInt::get(TruncTy, RHSC.
ashr(*ShiftAmt).
trunc(TypeBits - Amt));
2516 if (Cmp.isEquality() && Shr->
isExact() &&
C.isZero())
2517 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
2519 bool IsAShr = Shr->
getOpcode() == Instruction::AShr;
2520 const APInt *ShiftValC;
2522 if (Cmp.isEquality())
2540 assert(ShiftValC->
uge(
C) &&
"Expected simplify of compare");
2541 assert((IsUGT || !
C.isZero()) &&
"Expected X u< 0 to simplify");
2543 unsigned CmpLZ = IsUGT ?
C.countl_zero() : (
C - 1).
countl_zero();
2551 const APInt *ShiftAmtC;
2557 unsigned TypeBits =
C.getBitWidth();
2559 if (ShAmtVal >= TypeBits || ShAmtVal == 0)
2562 bool IsExact = Shr->
isExact();
2570 (
C - 1).isPowerOf2() &&
C.countLeadingZeros() > ShAmtVal) {
2576 APInt ShiftedC = (
C - 1).shl(ShAmtVal) + 1;
2577 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2583 APInt ShiftedC =
C.shl(ShAmtVal);
2584 if (ShiftedC.
ashr(ShAmtVal) ==
C)
2585 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2589 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2590 if (!
C.isMaxSignedValue() && !(
C + 1).shl(ShAmtVal).isMinSignedValue() &&
2591 (ShiftedC + 1).ashr(ShAmtVal) == (
C + 1))
2592 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2598 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2599 if ((ShiftedC + 1).ashr(ShAmtVal) == (
C + 1) ||
2600 (
C + 1).shl(ShAmtVal).isMinSignedValue())
2601 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2608 if (
C.getBitWidth() > 2 &&
C.getNumSignBits() <= ShAmtVal) {
2618 }
else if (!IsAShr) {
2622 APInt ShiftedC =
C.shl(ShAmtVal);
2623 if (ShiftedC.
lshr(ShAmtVal) ==
C)
2624 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2628 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2629 if ((ShiftedC + 1).lshr(ShAmtVal) == (
C + 1))
2630 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2634 if (!Cmp.isEquality())
2642 assert(((IsAShr &&
C.shl(ShAmtVal).ashr(ShAmtVal) ==
C) ||
2643 (!IsAShr &&
C.shl(ShAmtVal).lshr(ShAmtVal) ==
C)) &&
2644 "Expected icmp+shr simplify did not occur.");
2649 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy,
C << ShAmtVal));
2655 ConstantInt::get(ShrTy, (
C + 1).shl(ShAmtVal)));
2658 ConstantInt::get(ShrTy, (
C + 1).shl(ShAmtVal) - 1));
2665 Constant *Mask = ConstantInt::get(ShrTy, Val);
2667 return new ICmpInst(Pred,
And, ConstantInt::get(ShrTy,
C << ShAmtVal));
2690 const APInt *DivisorC;
2699 !
C.isStrictlyPositive()))
2705 Constant *MaskC = ConstantInt::get(Ty, SignMask | (*DivisorC - 1));
2709 return new ICmpInst(Pred,
And, ConstantInt::get(Ty,
C));
2736 assert(*C2 != 0 &&
"udiv 0, X should have been simplified already.");
2741 "icmp ugt X, UINT_MAX should have been simplified already.");
2743 ConstantInt::get(Ty, C2->
udiv(
C + 1)));
2748 assert(
C != 0 &&
"icmp ult X, 0 should have been simplified already.");
2750 ConstantInt::get(Ty, C2->
udiv(
C)));
2764 bool DivIsSigned = Div->
getOpcode() == Instruction::SDiv;
2774 if (Cmp.isEquality() && Div->
hasOneUse() &&
C.isSignBitSet() &&
2775 (!DivIsSigned ||
C.isMinSignedValue())) {
2800 if (!Cmp.isEquality() && DivIsSigned != Cmp.isSigned())
2819 bool ProdOV = (DivIsSigned ? Prod.
sdiv(*C2) : Prod.
udiv(*C2)) !=
C;
2832 int LoOverflow = 0, HiOverflow = 0;
2833 APInt LoBound, HiBound;
2838 HiOverflow = LoOverflow = ProdOV;
2847 LoBound = -(RangeSize - 1);
2848 HiBound = RangeSize;
2849 }
else if (
C.isStrictlyPositive()) {
2851 HiOverflow = LoOverflow = ProdOV;
2857 LoOverflow = HiOverflow = ProdOV ? -1 : 0;
2859 APInt DivNeg = -RangeSize;
2860 LoOverflow =
addWithOverflow(LoBound, HiBound, DivNeg,
true) ? -1 : 0;
2868 LoBound = RangeSize + 1;
2869 HiBound = -RangeSize;
2870 if (HiBound == *C2) {
2874 }
else if (
C.isStrictlyPositive()) {
2877 HiOverflow = LoOverflow = ProdOV ? -1 : 0;
2883 LoOverflow = HiOverflow = ProdOV;
2896 if (LoOverflow && HiOverflow)
2900 X, ConstantInt::get(Ty, LoBound));
2903 X, ConstantInt::get(Ty, HiBound));
2907 if (LoOverflow && HiOverflow)
2911 X, ConstantInt::get(Ty, LoBound));
2914 X, ConstantInt::get(Ty, HiBound));
2919 if (LoOverflow == +1)
2921 if (LoOverflow == -1)
2923 return new ICmpInst(Pred,
X, ConstantInt::get(Ty, LoBound));
2926 if (HiOverflow == +1)
2928 if (HiOverflow == -1)
2961 ((Cmp.isUnsigned() && HasNUW) || (Cmp.isSigned() && HasNSW)) &&
2963 return new ICmpInst(SwappedPred,
Y, ConstantInt::get(Ty, SubResult));
2971 if (Cmp.isEquality() &&
C.isZero() &&
3007 (*C2 & (
C - 1)) == (
C - 1))
3020 return new ICmpInst(SwappedPred,
Add, ConstantInt::get(Ty, ~
C));
3026 auto FoldConstant = [&](
bool Val) {
3030 cast<VectorType>(Op0->
getType())->getElementCount(), Res);
3034 switch (Table.to_ulong()) {
3036 return FoldConstant(
false);
3066 return FoldConstant(
true);
3089 unsigned BW =
C.getBitWidth();
3090 std::bitset<4> Table;
3091 auto ComputeTable = [&](
bool Op0Val,
bool Op1Val) {
3094 Res += isa<ZExtInst>(Ext0) ? 1 : -1;
3096 Res += isa<ZExtInst>(Ext1) ? 1 : -1;
3100 Table[0] = ComputeTable(
false,
false);
3101 Table[1] = ComputeTable(
false,
true);
3102 Table[2] = ComputeTable(
true,
false);
3103 Table[3] = ComputeTable(
true,
true);
3118 if ((
Add->hasNoSignedWrap() &&
3120 (
Add->hasNoUnsignedWrap() &&
3124 Cmp.isSigned() ?
C.ssub_ov(*C2, Overflow) :
C.usub_ov(*C2, Overflow);
3130 return new ICmpInst(Pred,
X, ConstantInt::get(Ty, NewC));
3134 C.isNonNegative() && (
C - *C2).isNonNegative() &&
3137 ConstantInt::get(Ty,
C - *C2));
3142 if (Cmp.isSigned()) {
3143 if (
Lower.isSignMask())
3145 if (
Upper.isSignMask())
3148 if (
Lower.isMinValue())
3150 if (
Upper.isMinValue())
3183 if (!
Add->hasOneUse())
3198 ConstantInt::get(Ty,
C * 2));
3213 ConstantInt::get(Ty, ~
C));
3218 Type *NewCmpTy = V->getType();
3220 if (shouldChangeType(Ty, NewCmpTy)) {
3221 if (CR.getActiveBits() <= NewCmpBW) {
3233 ConstantInt::get(NewCmpTy, EquivInt));
3256 Value *EqualVal = SI->getTrueValue();
3257 Value *UnequalVal = SI->getFalseValue();
3280 auto FlippedStrictness =
3282 PredB, cast<Constant>(RHS2));
3283 if (!FlippedStrictness)
3286 "basic correctness failure");
3287 RHS2 = FlippedStrictness->second;
3299 assert(
C &&
"Cmp RHS should be a constant int!");
3305 Value *OrigLHS, *OrigRHS;
3306 ConstantInt *C1LessThan, *C2Equal, *C3GreaterThan;
3307 if (Cmp.hasOneUse() &&
3310 assert(C1LessThan && C2Equal && C3GreaterThan);
3313 C1LessThan->
getValue(),
C->getValue(), Cmp.getPredicate());
3315 Cmp.getPredicate());
3317 C3GreaterThan->
getValue(),
C->getValue(), Cmp.getPredicate());
3328 if (TrueWhenLessThan)
3334 if (TrueWhenGreaterThan)
3344 auto *Bitcast = dyn_cast<BitCastInst>(Cmp.getOperand(0));
3349 Value *Op1 = Cmp.getOperand(1);
3350 Value *BCSrcOp = Bitcast->getOperand(0);
3351 Type *SrcType = Bitcast->getSrcTy();
3352 Type *DstType = Bitcast->getType();
3372 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(), 1));
3399 Type *XType =
X->getType();
3404 if (
auto *XVTy = dyn_cast<VectorType>(XType))
3418 if (!Cmp.getParent()->getParent()->hasFnAttribute(
3419 Attribute::NoImplicitFloat) &&
3420 Cmp.isEquality() && FPType->isIEEELikeFPTy()) {
3444 if (Cmp.isEquality() &&
C->isAllOnes() && Bitcast->hasOneUse()) {
3445 if (
Value *NotBCSrcOp =
3456 if (Cmp.isEquality() &&
C->isZero() && Bitcast->hasOneUse() &&
3458 if (
auto *VecTy = dyn_cast<FixedVectorType>(
X->getType())) {
3477 auto *VecTy = cast<VectorType>(SrcType);
3478 auto *EltTy = cast<IntegerType>(VecTy->getElementType());
3479 if (
C->isSplat(EltTy->getBitWidth())) {
3487 Value *NewC = ConstantInt::get(EltTy,
C->trunc(EltTy->getBitWidth()));
3488 return new ICmpInst(Pred, Extract, NewC);
3501 if (
auto *BO = dyn_cast<BinaryOperator>(Cmp.getOperand(0)))
3505 if (
auto *SI = dyn_cast<SelectInst>(Cmp.getOperand(0)))
3509 if (
auto *ConstRHS = dyn_cast<ConstantInt>(Cmp.getOperand(1)))
3513 if (
auto *TI = dyn_cast<TruncInst>(Cmp.getOperand(0)))
3517 if (
auto *
II = dyn_cast<IntrinsicInst>(Cmp.getOperand(0)))
3524 Value *Cmp0 = Cmp.getOperand(0);
3526 if (
C->isZero() && Cmp.isEquality() && Cmp0->
hasOneUse() &&
3528 m_ExtractValue<0>(m_Intrinsic<Intrinsic::ssub_with_overflow>(
3531 m_ExtractValue<0>(m_Intrinsic<Intrinsic::usub_with_overflow>(
3533 return new ICmpInst(Cmp.getPredicate(),
X,
Y);
3548 if (!Cmp.isEquality())
3553 Constant *
RHS = cast<Constant>(Cmp.getOperand(1));
3557 case Instruction::SRem:
3568 case Instruction::Add: {
3572 if (
Constant *C2 = dyn_cast<Constant>(BOp1)) {
3575 }
else if (
C.isZero()) {
3578 if (
Value *NegVal = dyn_castNegVal(BOp1))
3579 return new ICmpInst(Pred, BOp0, NegVal);
3580 if (
Value *NegVal = dyn_castNegVal(BOp0))
3581 return new ICmpInst(Pred, NegVal, BOp1);
3590 return new ICmpInst(Pred, BOp0, Neg);
3595 case Instruction::Xor:
3596 if (
Constant *BOC = dyn_cast<Constant>(BOp1)) {
3600 }
else if (
C.isZero()) {
3602 return new ICmpInst(Pred, BOp0, BOp1);
3605 case Instruction::Or: {
3626 Cond->getType() == Cmp.getType()) {
3664 case Instruction::UDiv:
3665 case Instruction::SDiv:
3675 return new ICmpInst(Pred, BOp0, BOp1);
3678 Instruction::Mul, BO->
getOpcode() == Instruction::SDiv, BOp1,
3679 Cmp.getOperand(1), BO);
3683 return new ICmpInst(Pred, YC, BOp0);
3687 if (BO->
getOpcode() == Instruction::UDiv &&
C.isZero()) {
3690 return new ICmpInst(NewPred, BOp1, BOp0);
3704 "Non-ctpop intrin in ctpop fold");
3740 Type *Ty =
II->getType();
3744 switch (
II->getIntrinsicID()) {
3745 case Intrinsic::abs:
3748 if (
C.isZero() ||
C.isMinSignedValue())
3749 return new ICmpInst(Pred,
II->getArgOperand(0), ConstantInt::get(Ty,
C));
3752 case Intrinsic::bswap:
3754 return new ICmpInst(Pred,
II->getArgOperand(0),
3755 ConstantInt::get(Ty,
C.byteSwap()));
3757 case Intrinsic::bitreverse:
3759 return new ICmpInst(Pred,
II->getArgOperand(0),
3760 ConstantInt::get(Ty,
C.reverseBits()));
3762 case Intrinsic::ctlz:
3763 case Intrinsic::cttz: {
3766 return new ICmpInst(Pred,
II->getArgOperand(0),
3772 unsigned Num =
C.getLimitedValue(
BitWidth);
3774 bool IsTrailing =
II->getIntrinsicID() == Intrinsic::cttz;
3777 APInt Mask2 = IsTrailing
3781 ConstantInt::get(Ty, Mask2));
3786 case Intrinsic::ctpop: {
3789 bool IsZero =
C.isZero();
3791 return new ICmpInst(Pred,
II->getArgOperand(0),
3798 case Intrinsic::fshl:
3799 case Intrinsic::fshr:
3800 if (
II->getArgOperand(0) ==
II->getArgOperand(1)) {
3801 const APInt *RotAmtC;
3805 return new ICmpInst(Pred,
II->getArgOperand(0),
3806 II->getIntrinsicID() == Intrinsic::fshl
3807 ? ConstantInt::get(Ty,
C.rotr(*RotAmtC))
3808 : ConstantInt::get(Ty,
C.rotl(*RotAmtC)));
3812 case Intrinsic::umax:
3813 case Intrinsic::uadd_sat: {
3816 if (
C.isZero() &&
II->hasOneUse()) {
3823 case Intrinsic::ssub_sat:
3826 return new ICmpInst(Pred,
II->getArgOperand(0),
II->getArgOperand(1));
3828 case Intrinsic::usub_sat: {
3833 return new ICmpInst(NewPred,
II->getArgOperand(0),
II->getArgOperand(1));
3848 assert(Cmp.isEquality());
3851 Value *Op0 = Cmp.getOperand(0);
3852 Value *Op1 = Cmp.getOperand(1);
3853 const auto *IIOp0 = dyn_cast<IntrinsicInst>(Op0);
3854 const auto *IIOp1 = dyn_cast<IntrinsicInst>(Op1);
3855 if (!IIOp0 || !IIOp1 || IIOp0->getIntrinsicID() != IIOp1->getIntrinsicID())
3858 switch (IIOp0->getIntrinsicID()) {
3859 case Intrinsic::bswap:
3860 case Intrinsic::bitreverse:
3863 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
3864 case Intrinsic::fshl:
3865 case Intrinsic::fshr: {
3868 if (IIOp0->getOperand(0) != IIOp0->getOperand(1))
3870 if (IIOp1->getOperand(0) != IIOp1->getOperand(1))
3872 if (IIOp0->getOperand(2) == IIOp1->getOperand(2))
3873 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
3879 unsigned OneUses = IIOp0->hasOneUse() + IIOp1->hasOneUse();
3884 Builder.
CreateSub(IIOp0->getOperand(2), IIOp1->getOperand(2));
3886 Op0->
getType(), IIOp0->getIntrinsicID(),
3887 {IIOp0->getOperand(0), IIOp0->getOperand(0), SubAmt});
3888 return new ICmpInst(Pred, IIOp1->getOperand(0), CombinedRotate);
3905 if (
auto *
II = dyn_cast<IntrinsicInst>(Cmp.getOperand(0))) {
3906 switch (
II->getIntrinsicID()) {
3909 case Intrinsic::fshl:
3910 case Intrinsic::fshr:
3911 if (Cmp.isEquality() &&
II->getArgOperand(0) ==
II->getArgOperand(1)) {
3913 if (
C.isZero() ||
C.isAllOnes())
3914 return new ICmpInst(Pred,
II->getArgOperand(0), Cmp.getOperand(1));
3928 case Instruction::Xor:
3932 case Instruction::And:
3936 case Instruction::Or:
3940 case Instruction::Mul:
3944 case Instruction::Shl:
3948 case Instruction::LShr:
3949 case Instruction::AShr:
3953 case Instruction::SRem:
3957 case Instruction::UDiv:
3961 case Instruction::SDiv:
3965 case Instruction::Sub:
3969 case Instruction::Add:
3987 if (!
II->hasOneUse())
4003 Value *Op0 =
II->getOperand(0);
4004 Value *Op1 =
II->getOperand(1);
4013 switch (
II->getIntrinsicID()) {
4016 "This function only works with usub_sat and uadd_sat for now!");
4017 case Intrinsic::uadd_sat:
4020 case Intrinsic::usub_sat:
4030 II->getBinaryOp(), *COp1,
II->getNoWrapKind());
4037 if (
II->getBinaryOp() == Instruction::Add)
4043 SatValCheck ? Instruction::BinaryOps::Or : Instruction::BinaryOps::And;
4045 std::optional<ConstantRange> Combination;
4046 if (CombiningOp == Instruction::BinaryOps::Or)
4058 Combination->getEquivalentICmp(EquivPred, EquivInt, EquivOffset);
4063 ConstantInt::get(Op1->
getType(), EquivInt));
4070 std::optional<ICmpInst::Predicate> NewPredicate = std::nullopt;
4075 NewPredicate = Pred;
4079 else if (
C.isAllOnes())
4087 else if (
C.isZero())
4104 if (!
C.isZero() && !
C.isAllOnes())
4115 if (
I->getIntrinsicID() == Intrinsic::scmp)
4129 switch (
II->getIntrinsicID()) {
4132 case Intrinsic::uadd_sat:
4133 case Intrinsic::usub_sat:
4138 case Intrinsic::ctpop: {
4143 case Intrinsic::scmp:
4144 case Intrinsic::ucmp:
4150 if (Cmp.isEquality())
4153 Type *Ty =
II->getType();
4155 switch (
II->getIntrinsicID()) {
4156 case Intrinsic::ctpop: {
4168 case Intrinsic::ctlz: {
4171 unsigned Num =
C.getLimitedValue();
4174 II->getArgOperand(0), ConstantInt::get(Ty, Limit));
4179 unsigned Num =
C.getLimitedValue();
4182 II->getArgOperand(0), ConstantInt::get(Ty, Limit));
4186 case Intrinsic::cttz: {
4188 if (!
II->hasOneUse())
4208 case Intrinsic::ssub_sat:
4212 return new ICmpInst(Pred,
II->getArgOperand(0),
II->getArgOperand(1));
4216 II->getArgOperand(1));
4220 II->getArgOperand(1));
4232 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
4233 Constant *RHSC = dyn_cast<Constant>(Op1);
4239 case Instruction::PHI:
4243 case Instruction::IntToPtr:
4252 case Instruction::Load:
4255 dyn_cast<GetElementPtrInst>(LHSI->
getOperand(0)))
4270 auto SimplifyOp = [&](
Value *
Op,
bool SelectCondIsTrue) ->
Value * {
4274 SI->getCondition(), Pred,
Op,
RHS,
DL, SelectCondIsTrue))
4275 return ConstantInt::get(
I.getType(), *Impl);
4280 Value *Op1 = SimplifyOp(SI->getOperand(1),
true);
4282 CI = dyn_cast<ConstantInt>(Op1);
4284 Value *Op2 = SimplifyOp(SI->getOperand(2),
false);
4286 CI = dyn_cast<ConstantInt>(Op2);
4288 auto Simplifies = [&](
Value *
Op,
unsigned Idx) {
4292 (isa<CmpIntrinsic>(SI->getOperand(
Idx)) &&
4303 bool Transform =
false;
4306 else if (Simplifies(Op1, 1) || Simplifies(Op2, 2)) {
4308 if (SI->hasOneUse())
4311 else if (CI && !CI->
isZero())
4330 unsigned Depth = 0) {
4333 if (V->getType()->getScalarSizeInBits() == 1)
4341 switch (
I->getOpcode()) {
4342 case Instruction::ZExt:
4345 case Instruction::SExt:
4349 case Instruction::And:
4350 case Instruction::Or:
4357 case Instruction::Xor:
4367 case Instruction::Select:
4371 case Instruction::Shl:
4374 case Instruction::LShr:
4377 case Instruction::AShr:
4381 case Instruction::Add:
4387 case Instruction::Sub:
4393 case Instruction::Call: {
4394 if (
auto *
II = dyn_cast<IntrinsicInst>(
I)) {
4395 switch (
II->getIntrinsicID()) {
4398 case Intrinsic::umax:
4399 case Intrinsic::smax:
4400 case Intrinsic::umin:
4401 case Intrinsic::smin:
4406 case Intrinsic::bitreverse:
4496 auto IsLowBitMask = [&]() {
4514 auto Check = [&]() {
4532 auto Check = [&]() {
4551 if (!IsLowBitMask())
4570 const APInt *C0, *C1;
4587 const APInt &MaskedBits = *C0;
4588 assert(MaskedBits != 0 &&
"shift by zero should be folded away already.");
4609 auto *XType =
X->getType();
4610 const unsigned XBitWidth = XType->getScalarSizeInBits();
4612 assert(
BitWidth.ugt(MaskedBits) &&
"shifts should leave some bits untouched");
4643 !
I.getOperand(0)->hasOneUse())
4668 assert(NarrowestTy ==
I.getOperand(0)->getType() &&
4669 "We did not look past any shifts while matching XShift though.");
4670 bool HadTrunc = WidestTy !=
I.getOperand(0)->getType();
4677 auto XShiftOpcode = XShift->
getOpcode();
4678 if (XShiftOpcode == YShift->
getOpcode())
4681 Value *
X, *XShAmt, *
Y, *YShAmt;
4688 if (!isa<Constant>(
X) && !isa<Constant>(
Y)) {
4690 if (!
match(
I.getOperand(0),
4716 unsigned MaximalPossibleTotalShiftAmount =
4719 APInt MaximalRepresentableShiftAmount =
4721 if (MaximalRepresentableShiftAmount.
ult(MaximalPossibleTotalShiftAmount))
4725 auto *NewShAmt = dyn_cast_or_null<Constant>(
4730 if (NewShAmt->getType() != WidestTy) {
4740 if (!
match(NewShAmt,
4742 APInt(WidestBitWidth, WidestBitWidth))))
4747 auto CanFold = [NewShAmt, WidestBitWidth, NarrowestShift, SQ,
4753 ? NewShAmt->getSplatValue()
4756 if (NewShAmtSplat &&
4762 if (
auto *
C = dyn_cast<Constant>(NarrowestShift->getOperand(0))) {
4766 unsigned MaxActiveBits = Known.
getBitWidth() - MinLeadZero;
4767 if (MaxActiveBits <= 1)
4773 if (
auto *
C = dyn_cast<Constant>(WidestShift->
getOperand(0))) {
4777 unsigned MaxActiveBits = Known.
getBitWidth() - MinLeadZero;
4778 if (MaxActiveBits <= 1)
4781 if (NewShAmtSplat) {
4784 if (AdjNewShAmt.
ule(MinLeadZero))
4798 Value *T0 = XShiftOpcode == Instruction::BinaryOps::LShr
4820 if (!
I.isEquality() &&
4830 NeedNegation =
false;
4833 NeedNegation =
true;
4839 if (
I.isEquality() &&
4855 bool MulHadOtherUses =
Mul && !
Mul->hasOneUse();
4856 if (MulHadOtherUses)
4860 Div->
getOpcode() == Instruction::UDiv ? Intrinsic::umul_with_overflow
4861 : Intrinsic::smul_with_overflow,
4862 X->getType(), {X, Y},
nullptr,
"mul");
4867 if (MulHadOtherUses)
4876 if (MulHadOtherUses)
4902 Type *Ty =
X->getType();
4916 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
4978 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5013 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5029 return new ICmpInst(PredOut, Op0, Op1);
5041 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5109 return new ICmpInst(NewPred, Op1, Zero);
5118 return new ICmpInst(NewPred, Op0, Zero);
5122 bool NoOp0WrapProblem =
false, NoOp1WrapProblem =
false;
5123 bool Op0HasNUW =
false, Op1HasNUW =
false;
5124 bool Op0HasNSW =
false, Op1HasNSW =
false;
5128 bool &HasNSW,
bool &HasNUW) ->
bool {
5129 if (isa<OverflowingBinaryOperator>(BO)) {
5135 }
else if (BO.
getOpcode() == Instruction::Or) {
5143 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr;
5147 NoOp0WrapProblem = hasNoWrapProblem(*BO0, Pred, Op0HasNSW, Op0HasNUW);
5151 NoOp1WrapProblem = hasNoWrapProblem(*BO1, Pred, Op1HasNSW, Op1HasNUW);
5156 if ((
A == Op1 ||
B == Op1) && NoOp0WrapProblem)
5162 if ((
C == Op0 ||
D == Op0) && NoOp1WrapProblem)
5167 if (
A &&
C && (
A ==
C ||
A ==
D ||
B ==
C ||
B ==
D) && NoOp0WrapProblem &&
5175 }
else if (
A ==
D) {
5179 }
else if (
B ==
C) {
5260 if (
A &&
C && NoOp0WrapProblem && NoOp1WrapProblem &&
5262 const APInt *AP1, *AP2;
5270 if (AP1Abs.
uge(AP2Abs)) {
5271 APInt Diff = *AP1 - *AP2;
5274 A, C3,
"", Op0HasNUW && Diff.
ule(*AP1), Op0HasNSW);
5277 APInt Diff = *AP2 - *AP1;
5280 C, C3,
"", Op1HasNUW && Diff.
ule(*AP2), Op1HasNSW);
5299 if (BO0 && BO0->
getOpcode() == Instruction::Sub) {
5303 if (BO1 && BO1->
getOpcode() == Instruction::Sub) {
5309 if (
A == Op1 && NoOp0WrapProblem)
5312 if (
C == Op0 && NoOp1WrapProblem)
5332 if (
B &&
D &&
B ==
D && NoOp0WrapProblem && NoOp1WrapProblem)
5336 if (
A &&
C &&
A ==
C && NoOp0WrapProblem && NoOp1WrapProblem)
5343 if (
Constant *RHSC = dyn_cast<Constant>(Op1))
5344 if (RHSC->isNotMinSignedValue())
5345 return new ICmpInst(
I.getSwappedPredicate(),
X,
5363 if (Op0HasNSW && Op1HasNSW) {
5376 if (GreaterThan &&
match(GreaterThan,
m_One()))
5383 if (((Op0HasNSW && Op1HasNSW) || (Op0HasNUW && Op1HasNUW)) &&
5395 if (NonZero && BO0 && BO1 && Op0HasNSW && Op1HasNSW)
5402 if (NonZero && BO0 && BO1 && Op0HasNUW && Op1HasNUW)
5413 else if (BO1 && BO1->
getOpcode() == Instruction::SRem &&
5443 case Instruction::Add:
5444 case Instruction::Sub:
5445 case Instruction::Xor: {
5452 if (
C->isSignMask()) {
5458 if (BO0->
getOpcode() == Instruction::Xor &&
C->isMaxSignedValue()) {
5460 NewPred =
I.getSwappedPredicate(NewPred);
5466 case Instruction::Mul: {
5467 if (!
I.isEquality())
5475 if (
unsigned TZs =
C->countr_zero()) {
5481 return new ICmpInst(Pred, And1, And2);
5486 case Instruction::UDiv:
5487 case Instruction::LShr:
5492 case Instruction::SDiv:
5498 case Instruction::AShr:
5503 case Instruction::Shl: {
5504 bool NUW = Op0HasNUW && Op1HasNUW;
5505 bool NSW = Op0HasNSW && Op1HasNSW;
5508 if (!NSW &&
I.isSigned())
5572 auto IsCondKnownTrue = [](
Value *Val) -> std::optional<bool> {
5574 return std::nullopt;
5579 return std::nullopt;
5583 if (!CmpXZ.has_value() && !CmpYZ.has_value())
5585 if (!CmpXZ.has_value()) {
5591 if (CmpYZ.has_value())
5615 if (!MinMaxCmpXZ.has_value()) {
5623 if (!MinMaxCmpXZ.has_value())
5639 return FoldIntoCmpYZ();
5666 return FoldIntoCmpYZ();
5675 return FoldIntoCmpYZ();
5697 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5701 if (
I.isEquality()) {
5736 Type *Ty =
A->getType();
5739 ConstantInt::get(Ty, 2))
5741 ConstantInt::get(Ty, 1));
5748 if (!
I.isEquality())
5751 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5755 if (
A == Op1 ||
B == Op1) {
5756 Value *OtherVal =
A == Op1 ?
B :
A;
5784 Value *OtherVal =
A == Op0 ?
B :
A;
5791 Value *
X =
nullptr, *
Y =
nullptr, *Z =
nullptr;
5797 }
else if (
A ==
D) {
5801 }
else if (
B ==
C) {
5805 }
else if (
B ==
D) {
5815 const APInt *C0, *C1;
5817 (*C0 ^ *C1).isNegatedPowerOf2();
5823 int(Op0->
hasOneUse()) + int(Op1->hasOneUse()) +
5825 if (XorIsNegP2 || UseCnt >= 2) {
5848 (Op0->
hasOneUse() || Op1->hasOneUse())) {
5853 MaskC->
countr_one() ==
A->getType()->getScalarSizeInBits())
5859 const APInt *AP1, *AP2;
5868 if (ShAmt < TypeBits && ShAmt != 0) {
5873 return new ICmpInst(NewPred,
Xor, ConstantInt::get(
A->getType(), CmpVal));
5883 if (ShAmt < TypeBits && ShAmt != 0) {
5887 I.getName() +
".mask");
5901 unsigned ASize = cast<IntegerType>(
A->getType())->getPrimitiveSizeInBits();
5903 if (ShAmt < ASize) {
5926 A->getType()->getScalarSizeInBits() ==
BitWidth * 2 &&
5927 (
I.getOperand(0)->hasOneUse() ||
I.getOperand(1)->hasOneUse())) {
5932 Add, ConstantInt::get(
A->getType(),
C.shl(1)));
5955 m_OneUse(m_Intrinsic<Intrinsic::fshr>(
5974 std::optional<bool> IsZero = std::nullopt;
6012 Constant *
C = ConstantInt::get(Res->X->getType(), Res->C);
6016 unsigned SrcBits =
X->getType()->getScalarSizeInBits();
6017 if (
auto *
II = dyn_cast<IntrinsicInst>(
X)) {
6018 if (
II->getIntrinsicID() == Intrinsic::cttz ||
6019 II->getIntrinsicID() == Intrinsic::ctlz) {
6020 unsigned MaxRet = SrcBits;
6040 assert(isa<CastInst>(ICmp.
getOperand(0)) &&
"Expected cast for operand 0");
6041 auto *CastOp0 = cast<CastInst>(ICmp.
getOperand(0));
6046 bool IsSignedExt = CastOp0->getOpcode() == Instruction::SExt;
6047 bool IsSignedCmp = ICmp.
isSigned();
6052 bool IsZext0 = isa<ZExtInst>(ICmp.
getOperand(0));
6053 bool IsZext1 = isa<ZExtInst>(ICmp.
getOperand(1));
6055 if (IsZext0 != IsZext1) {
6060 if (ICmp.
isEquality() &&
X->getType()->isIntOrIntVectorTy(1) &&
6061 Y->getType()->isIntOrIntVectorTy(1))
6068 auto *NonNegInst0 = dyn_cast<PossiblyNonNegInst>(ICmp.
getOperand(0));
6069 auto *NonNegInst1 = dyn_cast<PossiblyNonNegInst>(ICmp.
getOperand(1));
6071 bool IsNonNeg0 = NonNegInst0 && NonNegInst0->hasNonNeg();
6072 bool IsNonNeg1 = NonNegInst1 && NonNegInst1->hasNonNeg();
6074 if ((IsZext0 && IsNonNeg0) || (IsZext1 && IsNonNeg1))
6081 Type *XTy =
X->getType(), *YTy =
Y->getType();
6088 IsSignedExt ? Instruction::SExt : Instruction::ZExt;
6104 if (IsSignedCmp && IsSignedExt)
6117 Type *SrcTy = CastOp0->getSrcTy();
6125 if (IsSignedExt && IsSignedCmp)
6137 if (IsSignedCmp || !IsSignedExt || !isa<ConstantInt>(
C))
6156 Value *SimplifiedOp0 = simplifyIntToPtrRoundTripCast(ICmp.
getOperand(0));
6157 Value *SimplifiedOp1 = simplifyIntToPtrRoundTripCast(ICmp.
getOperand(1));
6158 if (SimplifiedOp0 || SimplifiedOp1)
6160 SimplifiedOp0 ? SimplifiedOp0 : ICmp.
getOperand(0),
6161 SimplifiedOp1 ? SimplifiedOp1 : ICmp.
getOperand(1));
6163 auto *CastOp0 = dyn_cast<CastInst>(ICmp.
getOperand(0));
6169 Value *Op0Src = CastOp0->getOperand(0);
6170 Type *SrcTy = CastOp0->getSrcTy();
6171 Type *DestTy = CastOp0->getDestTy();
6175 auto CompatibleSizes = [&](
Type *PtrTy,
Type *IntTy) {
6176 if (isa<VectorType>(PtrTy)) {
6177 PtrTy = cast<VectorType>(PtrTy)->getElementType();
6178 IntTy = cast<VectorType>(IntTy)->getElementType();
6182 if (CastOp0->getOpcode() == Instruction::PtrToInt &&
6183 CompatibleSizes(SrcTy, DestTy)) {
6184 Value *NewOp1 =
nullptr;
6185 if (
auto *PtrToIntOp1 = dyn_cast<PtrToIntOperator>(ICmp.
getOperand(1))) {
6186 Value *PtrSrc = PtrToIntOp1->getOperand(0);
6188 NewOp1 = PtrToIntOp1->getOperand(0);
6189 }
else if (
auto *RHSC = dyn_cast<Constant>(ICmp.
getOperand(1))) {
6198 if (CastOp0->getOpcode() == Instruction::IntToPtr &&
6199 CompatibleSizes(DestTy, SrcTy)) {
6200 Value *NewOp1 =
nullptr;
6201 if (
auto *IntToPtrOp1 = dyn_cast<IntToPtrInst>(ICmp.
getOperand(1))) {
6202 Value *IntSrc = IntToPtrOp1->getOperand(0);
6204 NewOp1 = IntToPtrOp1->getOperand(0);
6205 }
else if (
auto *RHSC = dyn_cast<Constant>(ICmp.
getOperand(1))) {
6223 case Instruction::Add:
6224 case Instruction::Sub:
6226 case Instruction::Mul:
6239 case Instruction::Add:
6244 case Instruction::Sub:
6249 case Instruction::Mul:
6258 bool IsSigned,
Value *LHS,
6262 if (OrigI.
isCommutative() && isa<Constant>(LHS) && !isa<Constant>(RHS))
6272 if (
auto *LHSTy = dyn_cast<VectorType>(
LHS->
getType()))
6287 Result->takeName(&OrigI);
6292 Result->takeName(&OrigI);
6294 if (
auto *Inst = dyn_cast<Instruction>(Result)) {
6296 Inst->setHasNoSignedWrap();
6298 Inst->setHasNoUnsignedWrap();
6321 const APInt *OtherVal,
6325 if (!isa<IntegerType>(MulVal->
getType()))
6328 auto *MulInstr = dyn_cast<Instruction>(MulVal);
6331 assert(MulInstr->getOpcode() == Instruction::Mul);
6333 auto *
LHS = cast<ZExtInst>(MulInstr->getOperand(0)),
6334 *
RHS = cast<ZExtInst>(MulInstr->getOperand(1));
6335 assert(
LHS->getOpcode() == Instruction::ZExt);
6336 assert(
RHS->getOpcode() == Instruction::ZExt);
6340 Type *TyA =
A->getType(), *TyB =
B->getType();
6342 WidthB = TyB->getPrimitiveSizeInBits();
6345 if (WidthB > WidthA) {
6360 if (
TruncInst *TI = dyn_cast<TruncInst>(U)) {
6363 if (TruncWidth > MulWidth)
6367 if (BO->getOpcode() != Instruction::And)
6369 if (
ConstantInt *CI = dyn_cast<ConstantInt>(BO->getOperand(1))) {
6370 const APInt &CVal = CI->getValue();
6386 switch (
I.getPredicate()) {
6393 if (MaxVal.
eq(*OtherVal))
6403 if (MaxVal.
eq(*OtherVal))
6417 if (WidthA < MulWidth)
6419 if (WidthB < MulWidth)
6423 {MulA, MulB},
nullptr,
"umul");
6434 if (
TruncInst *TI = dyn_cast<TruncInst>(U)) {
6435 if (TI->getType()->getPrimitiveSizeInBits() == MulWidth)
6440 assert(BO->getOpcode() == Instruction::And);
6442 ConstantInt *CI = cast<ConstantInt>(BO->getOperand(1));
6478 switch (
I.getPredicate()) {
6509 assert(DI && UI &&
"Instruction not defined\n");
6520 auto *Usr = cast<Instruction>(U);
6521 if (Usr != UI && !
DT.
dominates(DB, Usr->getParent()))
6532 auto *BI = dyn_cast_or_null<BranchInst>(BB->
getTerminator());
6533 if (!BI || BI->getNumSuccessors() != 2)
6535 auto *IC = dyn_cast<ICmpInst>(BI->getCondition());
6536 if (!IC || (IC->getOperand(0) != SI && IC->getOperand(1) != SI))
6583 const unsigned SIOpd) {
6584 assert((SIOpd == 1 || SIOpd == 2) &&
"Invalid select operand!");
6586 BasicBlock *Succ = SI->getParent()->getTerminator()->getSuccessor(1);
6600 SI->replaceUsesOutsideBlock(SI->getOperand(SIOpd), SI->getParent());
6610 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6639 if (!isa<Constant>(Op0) && Op0Known.
isConstant())
6642 if (!isa<Constant>(Op1) && Op1Known.
isConstant())
6671 if (!Cmp.hasOneUse())
6680 if (!isMinMaxCmp(
I)) {
6685 if (Op1Min == Op0Max)
6690 if (*CmpC == Op0Min + 1)
6692 ConstantInt::get(Op1->getType(), *CmpC - 1));
6702 if (Op1Max == Op0Min)
6707 if (*CmpC == Op0Max - 1)
6709 ConstantInt::get(Op1->getType(), *CmpC + 1));
6719 if (Op1Min == Op0Max)
6723 if (*CmpC == Op0Min + 1)
6725 ConstantInt::get(Op1->getType(), *CmpC - 1));
6730 if (Op1Max == Op0Min)
6734 if (*CmpC == Op0Max - 1)
6736 ConstantInt::get(Op1->getType(), *CmpC + 1));
6753 APInt Op0KnownZeroInverted = ~Op0Known.Zero;
6759 *LHSC != Op0KnownZeroInverted)
6765 Type *XTy =
X->getType();
6767 APInt C2 = Op0KnownZeroInverted;
6768 APInt C2Pow2 = (C2 & ~(*C1 - 1)) + *C1;
6774 auto *CmpC = ConstantInt::get(XTy, Log2C2 - Log2C1);
6784 (Op0Known & Op1Known) == Op0Known)
6790 if (Op1Min == Op0Max)
6794 if (Op1Max == Op0Min)
6798 if (Op1Min == Op0Max)
6802 if (Op1Max == Op0Min)
6810 if ((
I.isSigned() || (
I.isUnsigned() && !
I.hasSameSign())) &&
6813 I.setPredicate(
I.getUnsignedPredicate());
6848 bool IsSExt = ExtI->
getOpcode() == Instruction::SExt;
6850 auto CreateRangeCheck = [&] {
6865 }
else if (!IsSExt || HasOneUse) {
6870 return CreateRangeCheck();
6872 }
else if (IsSExt ?
C->isAllOnes() :
C->isOne()) {
6880 }
else if (!IsSExt || HasOneUse) {
6885 return CreateRangeCheck();
6899 Instruction::ICmp, Pred1,
X,
6909std::optional<std::pair<CmpPredicate, Constant *>>
6913 "Only for relational integer predicates.");
6919 bool WillIncrement =
6924 auto ConstantIsOk = [WillIncrement, IsSigned](
ConstantInt *
C) {
6925 return WillIncrement ? !
C->isMaxValue(IsSigned) : !
C->isMinValue(IsSigned);
6928 Constant *SafeReplacementConstant =
nullptr;
6929 if (
auto *CI = dyn_cast<ConstantInt>(
C)) {
6931 if (!ConstantIsOk(CI))
6932 return std::nullopt;
6933 }
else if (
auto *FVTy = dyn_cast<FixedVectorType>(
Type)) {
6934 unsigned NumElts = FVTy->getNumElements();
6935 for (
unsigned i = 0; i != NumElts; ++i) {
6936 Constant *Elt =
C->getAggregateElement(i);
6938 return std::nullopt;
6940 if (isa<UndefValue>(Elt))
6945 auto *CI = dyn_cast<ConstantInt>(Elt);
6946 if (!CI || !ConstantIsOk(CI))
6947 return std::nullopt;
6949 if (!SafeReplacementConstant)
6950 SafeReplacementConstant = CI;
6952 }
else if (isa<VectorType>(
C->getType())) {
6954 Value *SplatC =
C->getSplatValue();
6955 auto *CI = dyn_cast_or_null<ConstantInt>(SplatC);
6957 if (!CI || !ConstantIsOk(CI))
6958 return std::nullopt;
6961 return std::nullopt;
6968 if (
C->containsUndefOrPoisonElement()) {
6969 assert(SafeReplacementConstant &&
"Replacement constant not set");
6976 Constant *OneOrNegOne = ConstantInt::get(
Type, WillIncrement ? 1 : -1,
true);
6979 return std::make_pair(NewPred, NewC);
6991 Value *Op0 =
I.getOperand(0);
6992 Value *Op1 =
I.getOperand(1);
6993 auto *Op1C = dyn_cast<Constant>(Op1);
6997 auto FlippedStrictness =
6999 if (!FlippedStrictness)
7002 return new ICmpInst(FlippedStrictness->first, Op0, FlippedStrictness->second);
7020 I.setName(
I.getName() +
".not");
7031 Value *
A =
I.getOperand(0), *
B =
I.getOperand(1);
7032 assert(
A->getType()->isIntOrIntVectorTy(1) &&
"Bools only");
7038 switch (
I.getPredicate()) {
7047 switch (
I.getPredicate()) {
7057 switch (
I.getPredicate()) {
7066 return BinaryOperator::CreateXor(
A,
B);
7074 return BinaryOperator::CreateAnd(Builder.
CreateNot(
A),
B);
7082 return BinaryOperator::CreateAnd(Builder.
CreateNot(
B),
A);
7090 return BinaryOperator::CreateOr(Builder.
CreateNot(
A),
B);
7098 return BinaryOperator::CreateOr(Builder.
CreateNot(
B),
A);
7154 Value *
LHS = Cmp.getOperand(0), *
RHS = Cmp.getOperand(1);
7159 if (
auto *
I = dyn_cast<Instruction>(V))
7160 I->copyIRFlags(&Cmp);
7161 Module *M = Cmp.getModule();
7163 M, Intrinsic::vector_reverse, V->getType());
7171 return createCmpReverse(Pred, V1, V2);
7175 return createCmpReverse(Pred, V1,
RHS);
7179 return createCmpReverse(Pred,
LHS, V2);
7204 Constant *ScalarC =
C->getSplatValue(
true);
7223 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7227 auto UAddOvResultPat = m_ExtractValue<0>(
7229 if (
match(Op0, UAddOvResultPat) &&
7238 UAddOv = cast<ExtractValueInst>(Op0)->getAggregateOperand();
7239 else if (
match(Op1, UAddOvResultPat) &&
7242 UAddOv = cast<ExtractValueInst>(Op1)->getAggregateOperand();
7250 if (!
I.getOperand(0)->getType()->isPointerTy() ||
7252 I.getParent()->getParent(),
7253 I.getOperand(0)->getType()->getPointerAddressSpace())) {
7259 Op->isLaunderOrStripInvariantGroup()) {
7261 Op->getOperand(0),
I.getOperand(1));
7273 if (
I.getType()->isVectorTy())
7295 auto *LHSTy = dyn_cast<FixedVectorType>(
LHS->
getType());
7296 if (!LHSTy || !LHSTy->getElementType()->isIntegerTy())
7299 LHSTy->getNumElements() * LHSTy->getElementType()->getIntegerBitWidth();
7301 if (!
DL.isLegalInteger(NumBits))
7305 auto *ScalarTy = Builder.
getIntNTy(NumBits);
7320 if (
auto *
GEP = dyn_cast<GEPOperator>(Op0))
7324 if (
auto *SI = dyn_cast<SelectInst>(Op0))
7328 if (
auto *
MinMax = dyn_cast<MinMaxIntrinsic>(Op0))
7359 bool IsIntMinPosion =
C->isAllOnesValue();
7371 CxtI, IsIntMinPosion
7374 X, ConstantInt::get(
X->getType(),
SMin + 1)));
7380 CxtI, IsIntMinPosion
7383 X, ConstantInt::get(
X->getType(),
SMin)));
7396 auto CheckUGT1 = [](
const APInt &Divisor) {
return Divisor.ugt(1); };
7411 auto CheckNE0 = [](
const APInt &Shift) {
return !Shift.isZero(); };
7429 bool Changed =
false;
7431 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7438 if (Op0Cplxity < Op1Cplxity) {
7453 if (
Value *V = dyn_castNegVal(SelectTrue)) {
7454 if (V == SelectFalse)
7457 else if (
Value *V = dyn_castNegVal(SelectFalse)) {
7458 if (V == SelectTrue)
7499 if (
SelectInst *SI = dyn_cast<SelectInst>(
I.user_back())) {
7557 if (
I.isCommutative()) {
7558 if (
auto Pair = matchSymmetricPair(
I.getOperand(0),
I.getOperand(1))) {
7582 (Op0->
hasOneUse() || Op1->hasOneUse())) {
7598 assert(Op1->getType()->isPointerTy() &&
"Comparing pointer with non-pointer?");
7627 bool ConsumesOp0, ConsumesOp1;
7630 (ConsumesOp0 || ConsumesOp1)) {
7633 assert(InvOp0 && InvOp1 &&
7634 "Mismatch between isFreeToInvert and getFreelyInverted");
7635 return new ICmpInst(
I.getSwappedPredicate(), InvOp0, InvOp1);
7642 isa<IntegerType>(
X->getType())) {
7647 if (AddI->
getOpcode() == Instruction::Add &&
7648 OptimizeOverflowCheck(Instruction::Add,
false,
X,
Y, *AddI,
7649 Result, Overflow)) {
7667 if ((
I.isUnsigned() ||
I.isEquality()) &&
7670 Y->getType()->getScalarSizeInBits() == 1 &&
7671 (Op0->
hasOneUse() || Op1->hasOneUse())) {
7678 unsigned ShiftOpc = ShiftI->
getOpcode();
7679 if ((ExtOpc == Instruction::ZExt && ShiftOpc == Instruction::LShr) ||
7680 (ExtOpc == Instruction::SExt && ShiftOpc == Instruction::AShr)) {
7709 if (
auto *EVI = dyn_cast<ExtractValueInst>(Op0))
7710 if (
auto *ACXI = dyn_cast<AtomicCmpXchgInst>(EVI->getAggregateOperand()))
7711 if (EVI->getIndices()[0] == 0 && ACXI->getCompareOperand() == Op1 &&
7718 if (
I.getType()->isVectorTy())
7730 const APInt *C1, *C2;
7737 Type *InputTy =
A->getType();
7744 TruncC1.
setBit(InputBitWidth - 1);
7748 ConstantInt::get(InputTy, C2->
trunc(InputBitWidth)));
7754 return Changed ? &
I :
nullptr;
7768 if (MantissaWidth == -1)
return nullptr;
7772 bool LHSUnsigned = isa<UIToFPInst>(LHSI);
7774 if (
I.isEquality()) {
7776 bool IsExact =
false;
7777 APSInt RHSCvt(IntWidth, LHSUnsigned);
7786 if (*
RHS != RHSRoundInt) {
7806 if ((
int)IntWidth > MantissaWidth) {
7808 int Exp = ilogb(*
RHS);
7811 if (MaxExponent < (
int)IntWidth - !LHSUnsigned)
7817 if (MantissaWidth <= Exp && Exp <= (
int)IntWidth - !LHSUnsigned)
7826 assert(!
RHS->isNaN() &&
"NaN comparison not already folded!");
7829 switch (
I.getPredicate()) {
7919 APSInt RHSInt(IntWidth, LHSUnsigned);
7922 if (!
RHS->isZero()) {
7936 if (
RHS->isNegative())
7942 if (
RHS->isNegative())
7948 if (
RHS->isNegative())
7955 if (!
RHS->isNegative())
7961 if (
RHS->isNegative())
7967 if (
RHS->isNegative())
7973 if (
RHS->isNegative())
7980 if (!
RHS->isNegative())
8034 if (
C->isNegative())
8035 Pred =
I.getSwappedPredicate();
8050 if (!
C->isPosZero()) {
8051 if (!
C->isSmallestNormalized())
8064 switch (
I.getPredicate()) {
8090 switch (
I.getPredicate()) {
8115 assert(!
I.hasNoNaNs() &&
"fcmp should have simplified");
8120 assert(!
I.hasNoNaNs() &&
"fcmp should have simplified");
8134 return replacePredAndOp0(&
I,
I.getPredicate(),
X);
8156 if (!cast<Instruction>(
I.getOperand(0))->hasNoInfs())
8157 I.setHasNoInfs(
false);
8159 switch (
I.getPredicate()) {
8204 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
8209 Pred =
I.getSwappedPredicate();
8218 return new FCmpInst(Pred, Op0, Zero,
"", &
I);
8255 I.getFunction()->getDenormalMode(
8277 if (!FloorX && !CeilX) {
8281 Pred =
I.getSwappedPredicate();
8338 bool Changed =
false;
8349 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
8356 assert(OpType == Op1->getType() &&
"fcmp with different-typed operands?");
8380 if (
I.isCommutative()) {
8381 if (
auto Pair = matchSymmetricPair(
I.getOperand(0),
I.getOperand(1))) {
8403 return new FCmpInst(
I.getSwappedPredicate(),
X,
Y,
"", &
I);
8416 if (
SelectInst *SI = dyn_cast<SelectInst>(
I.user_back())) {
8485 Type *IntTy =
X->getType();
8497 case Instruction::Select:
8505 case Instruction::FSub:
8510 case Instruction::PHI:
8514 case Instruction::SIToFP:
8515 case Instruction::UIToFP:
8519 case Instruction::FDiv:
8523 case Instruction::Load:
8524 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(LHSI->
getOperand(0)))
8525 if (
auto *GV = dyn_cast<GlobalVariable>(
GEP->getOperand(0)))
8527 cast<LoadInst>(LHSI),
GEP, GV,
I))
8547 return new FCmpInst(
I.getSwappedPredicate(),
X, NegC,
"", &
I);
8566 X->getType()->getScalarType()->getFltSemantics();
8602 Constant *NewC = ConstantFP::get(
X->getType(), TruncC);
8616 if (
auto *VecTy = dyn_cast<VectorType>(OpType))
8628 Value *CanonLHS =
nullptr, *CanonRHS =
nullptr;
8629 match(Op0, m_Intrinsic<Intrinsic::canonicalize>(
m_Value(CanonLHS)));
8630 match(Op1, m_Intrinsic<Intrinsic::canonicalize>(
m_Value(CanonRHS)));
8633 if (CanonLHS == Op1)
8634 return new FCmpInst(Pred, Op1, Op1,
"", &
I);
8637 if (CanonRHS == Op0)
8638 return new FCmpInst(Pred, Op0, Op0,
"", &
I);
8641 if (CanonLHS && CanonRHS)
8642 return new FCmpInst(Pred, CanonLHS, CanonRHS,
"", &
I);
8645 if (
I.getType()->isVectorTy())
8649 return Changed ? &
I :
nullptr;
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 Value * rewriteGEPAsOffset(Value *Start, Value *Base, GEPNoWrapFlags NW, 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 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 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 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 Value * foldICmpWithLowBitMaskedVal(CmpPredicate Pred, Value *Op0, Value *Op1, const SimplifyQuery &Q, InstCombiner &IC)
Some comparisons can be simplified.
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 * foldICmpShlLHSC(ICmpInst &Cmp, Instruction *Shl, const APInt &C)
Fold icmp (shl nuw C2, Y), C.
static Instruction * foldFCmpWithFloorAndCeil(FCmpInst &I, InstCombinerImpl &IC)
static Instruction * foldICmpXorXX(ICmpInst &I, const SimplifyQuery &Q, InstCombinerImpl &IC)
static Instruction * foldICmpOfCmpIntrinsicWithConstant(CmpPredicate Pred, IntrinsicInst *I, const APInt &C, InstCombiner::BuilderTy &Builder)
static Instruction * processUMulZExtIdiom(ICmpInst &I, Value *MulVal, const APInt *OtherVal, InstCombinerImpl &IC)
Recognize and process idiom involving test for multiplication overflow.
static Instruction * foldSqrtWithFcmpZero(FCmpInst &I, InstCombinerImpl &IC)
Optimize sqrt(X) compared with zero.
static Instruction * foldFCmpFNegCommonOp(FCmpInst &I)
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 * foldICmpUSubSatOrUAddSatWithConstant(CmpPredicate Pred, SaturatingInst *II, const APInt &C, InstCombiner::BuilderTy &Builder)
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 bool canRewriteGEPAsOffset(Value *Start, Value *Base, GEPNoWrapFlags &NW, 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 * 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 * transformToIndexedCompare(GEPOperator *GEPLHS, Value *RHS, CmpPredicate Cond, const DataLayout &DL, InstCombiner &IC)
Converts (CMP GEPLHS, RHS) if this change would make RHS a constant.
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 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 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.
static void udivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder)
Dual division/remainder interface.
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.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
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.
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 isMask(unsigned numBits) const
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.
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.
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".
bool isIntPredicate() const
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
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 * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
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...
bool getEquivalentICmp(CmpInst::Predicate &Pred, APInt &RHS) const
Set up Pred and RHS such that ConstantRange::makeExactICmpRegion(Pred, RHS) == *this.
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 truncate(uint32_t BitWidth) const
Return a new range in the specified integer type, which must be strictly smaller than the current typ...
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.
iterator find(const_arg_type_t< KeyT > Val)
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.
Represents flags for the getelementptr instruction/expression.
bool hasNoUnsignedSignedWrap() const
bool hasNoUnsignedWrap() const
GEPNoWrapFlags intersectForOffsetAdd(GEPNoWrapFlags Other) const
Given (gep (gep p, x), y), determine the nowrap flags for (gep p, x+y).
static GEPNoWrapFlags none()
bool isInBounds() const
Test whether this is an inbounds GEP, as defined by LangRef.html.
Type * getSourceElementType() const
Value * getPointerOperand()
GEPNoWrapFlags getNoWrapFlags() const
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 getFlippedSignednessPredicate() const
For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->EQ.
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 * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
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 * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
ConstantInt * getFalse()
Get the constant value for i1 false.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
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 * 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.
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, bool AllowMultipleUses=false)
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 * 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 * foldICmpCommutative(CmpPredicate Pred, Value *Op0, Value *Op1, ICmpInst &CxtI)
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.
Instruction * foldICmpAddOpConst(Value *X, const APInt &C, CmpPredicate Pred)
Fold "icmp pred (X+C), X".
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 * foldSelectICmp(CmpPredicate Pred, SelectInst *SI, Value *RHS, const ICmpInst &I)
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)
Instruction * foldICmpWithMinMax(Instruction &I, MinMaxIntrinsic *MinMax, Value *Z, CmpPredicate Pred)
Fold icmp Pred min|max(X, Y), Z.
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 * visitICmpInst(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)
Instruction * foldGEPICmp(GEPOperator *GEPLHS, Value *RHS, CmpPredicate Cond, Instruction &I)
Fold comparisons between a GEP instruction and something else.
The core instruction combiner logic.
OverflowResult computeOverflowForSignedSub(const Value *LHS, const Value *RHS, const Instruction *CxtI) const
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< CmpPredicate, Constant * > > getFlippedStrictnessPredicateAndConstant(CmpPredicate Pred, Constant *C)
OverflowResult computeOverflowForUnsignedSub(const Value *LHS, const Value *RHS, const Instruction *CxtI) const
static bool isCanonicalPredicate(CmpPredicate Pred)
Predicate canonicalization reduces the number of patterns that need to be matched by other transforms...
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.
bool isVolatile() const
Return true if this is a load from a volatile memory location.
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.
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 * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
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.
cst_pred_ty< is_sign_mask > m_SignMask()
Match an integer or vector with only the sign bit(s) set.
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)
CmpClass_match< LHS, RHS, ICmpInst, true > m_c_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
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.
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.
ThreeOps_match< decltype(m_Value()), LHS, RHS, Instruction::Select, true > m_c_Select(const LHS &L, const RHS &R)
Match Select(C, LHS, RHS) or Select(C, RHS, LHS)
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::Shl, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWShl(const LHS &L, const RHS &R)
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.
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)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, 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.
Value * simplifyFCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q)
Given operands for an FCmpInst, fold the result or return null.
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.
Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
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.
bool isKnownNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the given value is known be negative (i.e.
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.
Value * simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an ICmpInst, fold the result or return null.
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.
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 isKnownNonEqual(const Value *V1, const Value *V2, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return true if the given values are known to be non-equal when defined.
@ 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()).
std::optional< DecomposedBitTest > decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate Pred, bool LookThroughTrunc=true, bool AllowNonZeroC=false)
Decompose an icmp into the form ((X & Mask) pred C) if possible.
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 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.
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 isStrictlyPositive() const
Returns true if this value is known to be positive.
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.