40#define DEBUG_TYPE "instcombine"
48 bool IsSigned =
false) {
51 Result = In1.
sadd_ov(In2, Overflow);
53 Result = In1.
uadd_ov(In2, Overflow);
61 bool IsSigned =
false) {
64 Result = In1.
ssub_ov(In2, Overflow);
66 Result = In1.
usub_ov(In2, Overflow);
74 for (
auto *U :
I.users())
96 }
else if (
C.isAllOnes()) {
122 if (LI->
isVolatile() || !GV || !GV->isConstant() ||
123 !GV->hasDefinitiveInitializer())
127 TypeSize EltSize =
DL.getTypeStoreSize(EltTy);
143 if (!ConstOffset.
ult(Stride))
151 uint64_t ArrayElementCount =
154 if (ArrayElementCount >
CLOpts.maxarray_size)
157 enum { Overdefined = -3, Undefined = -2 };
166 int FirstTrueElement = Undefined, SecondTrueElement = Undefined;
170 int FirstFalseElement = Undefined, SecondFalseElement = Undefined;
178 int TrueRangeEnd = Undefined, FalseRangeEnd = Undefined;
183 uint64_t MagicBitvector = 0;
188 for (
unsigned i = 0, e = ArrayElementCount; i != e; ++i,
Offset += Stride) {
202 CompareRHS,
DL, &
TLI);
210 if (TrueRangeEnd == (
int)i - 1)
212 if (FalseRangeEnd == (
int)i - 1)
229 if (FirstTrueElement == Undefined)
230 FirstTrueElement = TrueRangeEnd = i;
233 if (SecondTrueElement == Undefined)
234 SecondTrueElement = i;
236 SecondTrueElement = Overdefined;
239 if (TrueRangeEnd == (
int)i - 1)
242 TrueRangeEnd = Overdefined;
246 if (FirstFalseElement == Undefined)
247 FirstFalseElement = FalseRangeEnd = i;
250 if (SecondFalseElement == Undefined)
251 SecondFalseElement = i;
253 SecondFalseElement = Overdefined;
256 if (FalseRangeEnd == (
int)i - 1)
259 FalseRangeEnd = Overdefined;
264 if (i < 64 && IsTrueForElt)
265 MagicBitvector |= 1ULL << i;
270 if ((i & 8) == 0 && i >= 64 && SecondTrueElement == Overdefined &&
271 SecondFalseElement == Overdefined && TrueRangeEnd == Overdefined &&
272 FalseRangeEnd == Overdefined)
286 auto MaskIdx = [&](
Value *Idx) {
290 Idx =
Builder.CreateAnd(Idx, Mask);
297 if (SecondTrueElement != Overdefined) {
300 if (FirstTrueElement == Undefined)
303 Value *FirstTrueIdx = ConstantInt::get(Idx->
getType(), FirstTrueElement);
306 if (SecondTrueElement == Undefined)
311 Value *SecondTrueIdx = ConstantInt::get(Idx->
getType(), SecondTrueElement);
313 return BinaryOperator::CreateOr(C1, C2);
318 if (SecondFalseElement != Overdefined) {
321 if (FirstFalseElement == Undefined)
324 Value *FirstFalseIdx = ConstantInt::get(Idx->
getType(), FirstFalseElement);
327 if (SecondFalseElement == Undefined)
332 Value *SecondFalseIdx =
333 ConstantInt::get(Idx->
getType(), SecondFalseElement);
335 return BinaryOperator::CreateAnd(C1, C2);
340 if (TrueRangeEnd != Overdefined) {
341 assert(TrueRangeEnd != FirstTrueElement &&
"Should emit single compare");
345 if (FirstTrueElement) {
347 Idx =
Builder.CreateAdd(Idx, Offs);
351 ConstantInt::get(Idx->
getType(), TrueRangeEnd - FirstTrueElement + 1);
356 if (FalseRangeEnd != Overdefined) {
357 assert(FalseRangeEnd != FirstFalseElement &&
"Should emit single compare");
360 if (FirstFalseElement) {
362 Idx =
Builder.CreateAdd(Idx, Offs);
366 ConstantInt::get(Idx->
getType(), FalseRangeEnd - FirstFalseElement);
379 if (ArrayElementCount <= Idx->
getType()->getIntegerBitWidth())
382 Ty =
DL.getSmallestLegalIntType(
Init->getContext(), ArrayElementCount);
387 V =
Builder.CreateLShr(ConstantInt::get(Ty, MagicBitvector), V);
388 V =
Builder.CreateAnd(ConstantInt::get(Ty, 1), V);
413 while (!WorkList.
empty()) {
416 while (!WorkList.
empty()) {
417 if (Explored.
size() >= 100)
435 if (!
GEP->isInBounds() ||
count_if(
GEP->indices(), IsNonConst) > 1)
443 if (WorkList.
back() == V) {
459 for (
auto *PN : PHIs)
460 for (
Value *
Op : PN->incoming_values())
468 for (
Value *Val : Explored) {
474 if (Inst ==
Base || Inst ==
PHI || !Inst || !
PHI ||
478 if (
PHI->getParent() == Inst->getParent())
488 bool Before =
true) {
496 I = &*std::next(
I->getIterator());
497 Builder.SetInsertPoint(
I);
502 BasicBlock &Entry =
A->getParent()->getEntryBlock();
503 Builder.SetInsertPoint(&Entry, Entry.getFirstInsertionPt());
525 Base->getContext(),
DL.getIndexTypeSizeInBits(Start->getType()));
531 for (
Value *Val : Explored) {
539 PHI->getName() +
".idx",
PHI->getIterator());
544 for (
Value *Val : Explored) {
553 NewInsts[
GEP] = OffsetV;
555 NewInsts[
GEP] = Builder.CreateAdd(
556 Op, OffsetV,
GEP->getOperand(0)->getName() +
".add",
568 for (
Value *Val : Explored) {
575 for (
unsigned I = 0,
E =
PHI->getNumIncomingValues();
I <
E; ++
I) {
576 Value *NewIncoming =
PHI->getIncomingValue(
I);
578 auto It = NewInsts.
find(NewIncoming);
579 if (It != NewInsts.
end())
580 NewIncoming = It->second;
587 for (
Value *Val : Explored) {
593 Value *NewVal = Builder.CreateGEP(Builder.getInt8Ty(),
Base, NewInsts[Val],
594 Val->getName() +
".ptr", NW);
601 return NewInsts[Start];
687 if (
Base.Ptr == RHS && CanFold(
Base.LHSNW) && !
Base.isExpensive()) {
691 EmitGEPOffsets(
Base.LHSGEPs,
Base.LHSNW, IdxTy,
true);
699 RHS->getType()->getPointerAddressSpace())) {
730 if (GEPLHS->
getOperand(0) != GEPRHS->getOperand(0)) {
731 bool IndicesTheSame =
734 GEPRHS->getPointerOperand()->getType() &&
738 if (GEPLHS->
getOperand(i) != GEPRHS->getOperand(i)) {
739 IndicesTheSame =
false;
745 if (IndicesTheSame &&
753 if (GEPLHS->
isInBounds() && GEPRHS->isInBounds() &&
755 (GEPRHS->hasAllConstantIndices() || GEPRHS->hasOneUse()) &&
759 Value *LOffset = EmitGEPOffset(GEPLHS);
760 Value *ROffset = EmitGEPOffset(GEPRHS);
767 if (LHSIndexTy != RHSIndexTy) {
770 ROffset =
Builder.CreateTrunc(ROffset, LHSIndexTy);
772 LOffset =
Builder.CreateTrunc(LOffset, RHSIndexTy);
781 if (GEPLHS->
getOperand(0) == GEPRHS->getOperand(0) &&
785 unsigned NumDifferences = 0;
786 unsigned DiffOperand = 0;
787 for (
unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i)
788 if (GEPLHS->
getOperand(i) != GEPRHS->getOperand(i)) {
790 Type *RHSType = GEPRHS->getOperand(i)->getType();
801 if (NumDifferences++)
806 if (NumDifferences == 0)
814 Value *RHSV = GEPRHS->getOperand(DiffOperand);
815 return NewICmp(NW, LHSV, RHSV);
819 if (
Base.Ptr && !
Base.isExpensive()) {
821 bool DoFold = CanFold(
Base.LHSNW &
Base.RHSNW);
823 if (!DoFold &&
Base.Ptr->getType()->isPointerTy()) {
827 unsigned BW =
DL.getIndexTypeSizeInBits(GEPLHS->
getType());
832 DL, LOff,
true) ==
Base.Ptr &&
833 RHS->stripAndAccumulateConstantOffsets(
834 DL, ROff,
true) ==
Base.Ptr)
846 return NewICmp(
Base.LHSNW &
Base.RHSNW, L, R);
873 bool Captured =
false;
878 CmpCaptureTracker(
AllocaInst *Alloca) : Alloca(Alloca) {}
880 void tooManyUses()
override { Captured =
true; }
892 ICmps[ICmp] |= 1u << U->getOperandNo();
901 CmpCaptureTracker Tracker(Alloca);
903 if (Tracker.Captured)
907 for (
auto [ICmp,
Operands] : Tracker.ICmps) {
913 auto *Res = ConstantInt::get(ICmp->getType(),
939 assert(!!
C &&
"C should not be zero!");
955 ConstantInt::get(
X->getType(), -
C));
967 ConstantInt::get(
X->getType(),
SMax -
C));
978 ConstantInt::get(
X->getType(),
SMax - (
C - 1)));
987 assert(
I.isEquality() &&
"Cannot fold icmp gt/lt");
990 if (
I.getPredicate() ==
I.ICMP_NE)
992 return new ICmpInst(Pred, LHS, RHS);
1011 return getICmp(
I.ICMP_UGT,
A,
1012 ConstantInt::get(
A->getType(), AP2.
logBase2()));
1024 if (IsAShr && AP1 == AP2.
ashr(Shift)) {
1028 return getICmp(
I.ICMP_UGE,
A, ConstantInt::get(
A->getType(), Shift));
1029 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1030 }
else if (AP1 == AP2.
lshr(Shift)) {
1031 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1037 auto *TorF = ConstantInt::get(
I.getType(),
I.getPredicate() ==
I.ICMP_NE);
1046 assert(
I.isEquality() &&
"Cannot fold icmp gt/lt");
1049 if (
I.getPredicate() ==
I.ICMP_NE)
1051 return new ICmpInst(Pred, LHS, RHS);
1060 if (!AP1 && AP2TrailingZeros != 0)
1063 ConstantInt::get(
A->getType(), AP2.
getBitWidth() - AP2TrailingZeros));
1071 if (Shift > 0 && AP2.
shl(Shift) == AP1)
1072 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1076 auto *TorF = ConstantInt::get(
I.getType(),
I.getPredicate() ==
I.ICMP_NE);
1105 if (NewWidth != 7 && NewWidth != 15 && NewWidth != 31)
1129 if (U == AddWithCst)
1147 I.getModule(), Intrinsic::sadd_with_overflow, NewType);
1155 Value *TruncA = Builder.CreateTrunc(
A, NewType,
A->getName() +
".trunc");
1156 Value *TruncB = Builder.CreateTrunc(
B, NewType,
B->getName() +
".trunc");
1157 CallInst *
Call = Builder.CreateCall(
F, {TruncA, TruncB},
"sadd");
1158 Value *
Add = Builder.CreateExtractValue(
Call, 0,
"sadd.result");
1176 if (!
I.isEquality())
1207 APInt(XBitWidth, XBitWidth - 1))))
1234 return new ICmpInst(Pred,
B, Cmp.getOperand(1));
1236 return new ICmpInst(Pred,
A, Cmp.getOperand(1));
1253 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1265 return new ICmpInst(Pred,
Y, Cmp.getOperand(1));
1271 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1274 if (BO0->hasNoUnsignedWrap() || BO0->hasNoSignedWrap()) {
1282 return new ICmpInst(Pred,
Y, Cmp.getOperand(1));
1287 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1303 return new ICmpInst(Pred, Stripped,
1316 const APInt *Mask, *Neg;
1332 auto *NewAnd =
Builder.CreateAnd(Num, *Mask);
1335 return new ICmpInst(Pred, NewAnd, Zero);
1356 Value *Op0 = Cmp.getOperand(0), *Op1 = Cmp.getOperand(1);
1372 for (
Value *V : Phi->incoming_values()) {
1380 PHINode *NewPhi =
Builder.CreatePHI(Cmp.getType(), Phi->getNumOperands());
1381 for (
auto [V, Pred] :
zip(
Ops, Phi->blocks()))
1396 Value *
X = Cmp.getOperand(0), *
Y = Cmp.getOperand(1);
1429 if (Cmp.isEquality() || (IsSignBit &&
hasBranchUse(Cmp)))
1434 if (Cmp.hasOneUse() &&
1448 if (!
match(BI->getCondition(),
1453 if (
DT.dominates(Edge0, Cmp.getParent())) {
1454 if (
auto *V = handleDomCond(DomPred, DomC))
1458 if (
DT.dominates(Edge1, Cmp.getParent()))
1474 Type *SrcTy =
X->getType();
1476 SrcBits = SrcTy->getScalarSizeInBits();
1480 if (shouldChangeType(Trunc->
getType(), SrcTy)) {
1482 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy,
C.sext(SrcBits)));
1484 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy,
C.zext(SrcBits)));
1487 if (
C.isOne() &&
C.getBitWidth() > 1) {
1492 ConstantInt::get(V->getType(), 1));
1504 auto NewPred = (Pred == Cmp.ICMP_EQ) ? Cmp.ICMP_UGE : Cmp.ICMP_ULT;
1506 ConstantInt::get(SrcTy, DstBits - Pow2->
logBase2()));
1512 Pred,
Y, ConstantInt::get(SrcTy,
C.logBase2() - Pow2->
logBase2()));
1518 if (!SrcTy->isVectorTy() && shouldChangeType(DstBits, SrcBits)) {
1522 Constant *WideC = ConstantInt::get(SrcTy,
C.zext(SrcBits));
1531 if ((
Known.Zero |
Known.One).countl_one() >= SrcBits - DstBits) {
1533 APInt NewRHS =
C.zext(SrcBits);
1535 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy, NewRHS));
1547 DstBits == SrcBits - ShAmt) {
1564 bool YIsSExt =
false;
1567 unsigned NoWrapFlags =
cast<TruncInst>(Cmp.getOperand(0))->getNoWrapKind() &
1569 if (Cmp.isSigned()) {
1580 if (
X->getType() !=
Y->getType() &&
1581 (!Cmp.getOperand(0)->hasOneUse() || !Cmp.getOperand(1)->hasOneUse()))
1583 if (!isDesirableIntType(
X->getType()->getScalarSizeInBits()) &&
1584 isDesirableIntType(
Y->getType()->getScalarSizeInBits())) {
1586 Pred = Cmp.getSwappedPredicate(Pred);
1591 else if (!Cmp.isSigned() &&
1605 Type *TruncTy = Cmp.getOperand(0)->getType();
1610 if (isDesirableIntType(TruncBits) &&
1611 !isDesirableIntType(
X->getType()->getScalarSizeInBits()))
1634 bool TrueIfSigned =
false;
1651 if (
Xor->hasOneUse()) {
1653 if (!Cmp.isEquality() && XorC->
isSignMask()) {
1654 Pred = Cmp.getFlippedSignednessPredicate();
1655 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(),
C ^ *XorC));
1660 Pred = Cmp.getFlippedSignednessPredicate();
1661 Pred = Cmp.getSwappedPredicate(Pred);
1662 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(),
C ^ *XorC));
1669 if (*XorC == ~
C && (
C + 1).isPowerOf2())
1672 if (*XorC ==
C && (
C + 1).isPowerOf2())
1677 if (*XorC == -
C &&
C.isPowerOf2())
1679 ConstantInt::get(
X->getType(), ~
C));
1681 if (*XorC ==
C && (-
C).isPowerOf2())
1683 ConstantInt::get(
X->getType(), ~
C));
1705 const APInt *ShiftC;
1710 Type *XType =
X->getType();
1716 return new ICmpInst(Pred,
Add, ConstantInt::get(XType, Bound));
1725 if (!Shift || !Shift->
isShift())
1733 unsigned ShiftOpcode = Shift->
getOpcode();
1734 bool IsShl = ShiftOpcode == Instruction::Shl;
1737 APInt NewAndCst, NewCmpCst;
1738 bool AnyCmpCstBitsShiftedOut;
1739 if (ShiftOpcode == Instruction::Shl) {
1747 NewCmpCst = C1.
lshr(*C3);
1748 NewAndCst = C2.
lshr(*C3);
1749 AnyCmpCstBitsShiftedOut = NewCmpCst.
shl(*C3) != C1;
1750 }
else if (ShiftOpcode == Instruction::LShr) {
1755 NewCmpCst = C1.
shl(*C3);
1756 NewAndCst = C2.
shl(*C3);
1757 AnyCmpCstBitsShiftedOut = NewCmpCst.
lshr(*C3) != C1;
1763 assert(ShiftOpcode == Instruction::AShr &&
"Unknown shift opcode");
1764 NewCmpCst = C1.
shl(*C3);
1765 NewAndCst = C2.
shl(*C3);
1766 AnyCmpCstBitsShiftedOut = NewCmpCst.
ashr(*C3) != C1;
1767 if (NewAndCst.
ashr(*C3) != C2)
1771 if (AnyCmpCstBitsShiftedOut) {
1781 Shift->
getOperand(0), ConstantInt::get(
And->getType(), NewAndCst));
1782 return new ICmpInst(Cmp.getPredicate(), NewAnd,
1783 ConstantInt::get(
And->getType(), NewCmpCst));
1800 return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
1814 return new TruncInst(
And->getOperand(0), Cmp.getType());
1825 ConstantInt::get(
X->getType(), ~*C2));
1830 ConstantInt::get(
X->getType(), -*C2));
1833 if (!
And->hasOneUse())
1836 if (Cmp.isEquality() && C1.
isZero()) {
1854 Constant *NegBOC = ConstantInt::get(
And->getType(), -NewC2);
1856 return new ICmpInst(NewPred,
X, NegBOC);
1874 if (!Cmp.getType()->isVectorTy()) {
1875 Type *WideType = W->getType();
1877 Constant *ZextC1 = ConstantInt::get(WideType, C1.
zext(WideScalarBits));
1878 Constant *ZextC2 = ConstantInt::get(WideType, C2->
zext(WideScalarBits));
1880 return new ICmpInst(Cmp.getPredicate(), NewAnd, ZextC1);
1891 if (!Cmp.isSigned() && C1.
isZero() &&
And->getOperand(0)->hasOneUse() &&
1898 unsigned UsesRemoved = 0;
1899 if (
And->hasOneUse())
1901 if (
Or->hasOneUse())
1908 if (UsesRemoved >= RequireUsesRemoved) {
1912 One,
Or->getName());
1914 return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
1928 if (!Cmp.getParent()->getParent()->hasFnAttribute(
1929 Attribute::NoImplicitFloat) &&
1932 Type *FPType = V->getType()->getScalarType();
1933 if (FPType->isIEEELikeFPTy() && (C1.
isZero() || C1 == *C2)) {
1934 APInt ExponentMask =
1936 if (*C2 == ExponentMask) {
1937 unsigned Mask = C1.
isZero()
1971 Constant *MinSignedC = ConstantInt::get(
1975 return new ICmpInst(NewPred,
X, MinSignedC);
1990 if (!Cmp.isEquality())
2000 if (
C.getBitWidth() > 1 && (
C.isZero() ||
C.isOne()) &&
2004 return new ICmpInst(Pred, MatchedX, Cmp.getOperand(1));
2008 return new TruncInst(MatchedX, Cmp.getType());
2012 if (
And->hasOneUse()) {
2013 Value *Trunc =
Builder.CreateTrunc(MatchedX, Cmp.getType());
2021 if (Cmp.getOperand(1) ==
Y &&
C.isNegatedPowerOf2()) {
2032 X->getType()->isIntOrIntVectorTy(1) && (
C.isZero() ||
C.isOne())) {
2038 return BinaryOperator::CreateAnd(TruncY,
X);
2056 const APInt *Addend, *Msk;
2060 APInt NewComperand = (
C - *Addend) & *Msk;
2061 Value *MaskA =
Builder.CreateAnd(
A, ConstantInt::get(
A->getType(), *Msk));
2063 ConstantInt::get(MaskA->
getType(), NewComperand));
2085 while (!WorkList.
empty()) {
2086 auto MatchOrOperatorArgument = [&](
Value *OrOperatorArgument) {
2089 if (
match(OrOperatorArgument,
2095 if (
match(OrOperatorArgument,
2105 Value *OrOperatorLhs, *OrOperatorRhs;
2107 if (!
match(CurrentValue,
2112 MatchOrOperatorArgument(OrOperatorRhs);
2113 MatchOrOperatorArgument(OrOperatorLhs);
2118 Value *LhsCmp = Builder.CreateICmp(Pred, CmpValues.
rbegin()->first,
2119 CmpValues.
rbegin()->second);
2121 for (
auto It = CmpValues.
rbegin() + 1; It != CmpValues.
rend(); ++It) {
2122 Value *RhsCmp = Builder.CreateICmp(Pred, It->first, It->second);
2123 LhsCmp = Builder.CreateBinOp(BOpc, LhsCmp, RhsCmp);
2139 ConstantInt::get(V->getType(), 1));
2142 Value *OrOp0 =
Or->getOperand(0), *OrOp1 =
Or->getOperand(1);
2149 Builder.CreateXor(OrOp1, ConstantInt::get(OrOp1->getType(),
C));
2150 return new ICmpInst(Pred, OrOp0, NewC);
2154 if (
match(OrOp1,
m_APInt(MaskC)) && Cmp.isEquality()) {
2155 if (*MaskC ==
C && (
C + 1).isPowerOf2()) {
2160 return new ICmpInst(Pred, OrOp0, OrOp1);
2167 if (
Or->hasOneUse()) {
2169 Constant *NewC = ConstantInt::get(
Or->getType(),
C ^ (*MaskC));
2181 Constant *NewC = ConstantInt::get(
X->getType(), TrueIfSigned ? 1 : 0);
2209 if (!Cmp.isEquality() || !
C.isZero() || !
Or->hasOneUse())
2240 if (
X ==
Mul->getOperand(1) && !Cmp.isSigned()) {
2242 bool IsSqr =
C == R * R;
2245 if (Cmp.isEquality() &&
2246 (
Mul->hasNoUnsignedWrap() || (
Mul->hasNoSignedWrap() &&
C.isZero()))) {
2254 return new ICmpInst(Pred,
X, ConstantInt::get(MulTy, R));
2259 if (
Mul->hasNoUnsignedWrap()) {
2262 return new ICmpInst(Pred,
X, ConstantInt::get(MulTy, R));
2276 return new ICmpInst(Cmp.getStrictPredicate(),
X,
2277 ConstantInt::get(MulTy, R));
2300 if (Cmp.isEquality()) {
2302 if (
Mul->hasNoSignedWrap() &&
C.srem(*MulC).isZero()) {
2303 Constant *NewC = ConstantInt::get(MulTy,
C.sdiv(*MulC));
2311 if (
C.urem(*MulC).isZero()) {
2314 if ((*MulC & 1).isOne() ||
Mul->hasNoUnsignedWrap()) {
2315 Constant *NewC = ConstantInt::get(MulTy,
C.udiv(*MulC));
2328 if (
C.isMinSignedValue() && MulC->
isAllOnes())
2334 NewC = ConstantInt::get(
2338 "Unexpected predicate");
2339 NewC = ConstantInt::get(
2344 NewC = ConstantInt::get(
2348 "Unexpected predicate");
2349 NewC = ConstantInt::get(
2354 return NewC ?
new ICmpInst(Pred,
X, NewC) :
nullptr;
2366 unsigned TypeBits =
C.getBitWidth();
2368 if (Cmp.isUnsigned()) {
2388 return new ICmpInst(Pred,
Y, ConstantInt::get(ShiftType, CLog2));
2389 }
else if (Cmp.isSigned() && C2->
isOne()) {
2390 Constant *BitWidthMinusOne = ConstantInt::get(ShiftType, TypeBits - 1);
2411 const APInt *ShiftVal;
2441 const APInt *ShiftAmt;
2447 unsigned TypeBits =
C.getBitWidth();
2448 if (ShiftAmt->
uge(TypeBits))
2460 APInt ShiftedC =
C.ashr(*ShiftAmt);
2461 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2464 C.ashr(*ShiftAmt).shl(*ShiftAmt) ==
C) {
2465 APInt ShiftedC =
C.ashr(*ShiftAmt);
2466 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2473 assert(!
C.isMinSignedValue() &&
"Unexpected icmp slt");
2474 APInt ShiftedC = (
C - 1).ashr(*ShiftAmt) + 1;
2475 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2485 APInt ShiftedC =
C.lshr(*ShiftAmt);
2486 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2489 C.lshr(*ShiftAmt).shl(*ShiftAmt) ==
C) {
2490 APInt ShiftedC =
C.lshr(*ShiftAmt);
2491 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2498 assert(
C.ugt(0) &&
"ult 0 should have been eliminated");
2499 APInt ShiftedC = (
C - 1).lshr(*ShiftAmt) + 1;
2500 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2504 if (Cmp.isEquality() && Shl->
hasOneUse()) {
2510 Constant *LShrC = ConstantInt::get(ShType,
C.lshr(*ShiftAmt));
2515 bool TrueIfSigned =
false;
2527 if (Cmp.isUnsigned() && Shl->
hasOneUse()) {
2529 if ((
C + 1).isPowerOf2() &&
2537 if (
C.isPowerOf2() &&
2567 Pred, ConstantInt::get(ShType->
getContext(),
C))) {
2568 CmpPred = FlippedStrictness->first;
2576 ConstantInt::get(TruncTy, RHSC.
ashr(*ShiftAmt).
trunc(TypeBits - Amt));
2578 Builder.CreateTrunc(
X, TruncTy,
"",
false,
2595 if (Cmp.isEquality() && Shr->
isExact() &&
C.isZero())
2596 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
2598 bool IsAShr = Shr->
getOpcode() == Instruction::AShr;
2599 const APInt *ShiftValC;
2601 if (Cmp.isEquality())
2619 assert(ShiftValC->
uge(
C) &&
"Expected simplify of compare");
2620 assert((IsUGT || !
C.isZero()) &&
"Expected X u< 0 to simplify");
2622 unsigned CmpLZ = IsUGT ?
C.countl_zero() : (
C - 1).
countl_zero();
2630 const APInt *ShiftAmtC;
2636 unsigned TypeBits =
C.getBitWidth();
2638 if (ShAmtVal >= TypeBits || ShAmtVal == 0)
2641 bool IsExact = Shr->
isExact();
2649 (
C - 1).isPowerOf2() &&
C.countLeadingZeros() > ShAmtVal) {
2655 APInt ShiftedC = (
C - 1).shl(ShAmtVal) + 1;
2656 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2662 APInt ShiftedC =
C.shl(ShAmtVal);
2663 if (ShiftedC.
ashr(ShAmtVal) ==
C)
2664 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2668 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2669 if (!
C.isMaxSignedValue() && !(
C + 1).shl(ShAmtVal).isMinSignedValue() &&
2670 (ShiftedC + 1).ashr(ShAmtVal) == (
C + 1))
2671 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2677 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2678 if ((ShiftedC + 1).ashr(ShAmtVal) == (
C + 1) ||
2679 (
C + 1).shl(ShAmtVal).isMinSignedValue())
2680 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2687 if (
C.getBitWidth() > 2 &&
C.getNumSignBits() <= ShAmtVal) {
2697 }
else if (!IsAShr) {
2701 APInt ShiftedC =
C.shl(ShAmtVal);
2702 if (ShiftedC.
lshr(ShAmtVal) ==
C)
2703 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2707 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2708 if ((ShiftedC + 1).lshr(ShAmtVal) == (
C + 1))
2709 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2713 if (!Cmp.isEquality())
2721 assert(((IsAShr &&
C.shl(ShAmtVal).ashr(ShAmtVal) ==
C) ||
2722 (!IsAShr &&
C.shl(ShAmtVal).lshr(ShAmtVal) ==
C)) &&
2723 "Expected icmp+shr simplify did not occur.");
2728 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy,
C << ShAmtVal));
2734 Constant *Mask = ConstantInt::get(ShrTy, Val);
2736 return new ICmpInst(Pred,
And, ConstantInt::get(ShrTy,
C << ShAmtVal));
2753 const APInt *DivisorC;
2762 "ult X, 0 should have been simplified already.");
2767 if (!NormalizedC.
uge(DivisorC->
abs() - 1))
2790 const APInt *DivisorC;
2799 !
C.isStrictlyPositive()))
2805 Constant *MaskC = ConstantInt::get(Ty, SignMask | (*DivisorC - 1));
2809 return new ICmpInst(Pred,
And, ConstantInt::get(Ty,
C));
2836 assert(*C2 != 0 &&
"udiv 0, X should have been simplified already.");
2841 "icmp ugt X, UINT_MAX should have been simplified already.");
2843 ConstantInt::get(Ty, C2->
udiv(
C + 1)));
2848 assert(
C != 0 &&
"icmp ult X, 0 should have been simplified already.");
2850 ConstantInt::get(Ty, C2->
udiv(
C)));
2864 bool DivIsSigned = Div->
getOpcode() == Instruction::SDiv;
2874 if (Cmp.isEquality() && Div->
hasOneUse() &&
C.isSignBitSet() &&
2875 (!DivIsSigned ||
C.isMinSignedValue())) {
2876 Value *XBig =
Builder.CreateICmp(Pred,
X, ConstantInt::get(Ty,
C));
2877 Value *YOne =
Builder.CreateICmp(Pred,
Y, ConstantInt::get(Ty, 1));
2903 if (!Cmp.isEquality() && DivIsSigned != Cmp.isSigned()) {
2907 DivIsSigned =
false;
2926 bool ProdOV = (DivIsSigned ? Prod.
sdiv(*C2) : Prod.
udiv(*C2)) !=
C;
2939 int LoOverflow = 0, HiOverflow = 0;
2940 APInt LoBound, HiBound;
2945 HiOverflow = LoOverflow = ProdOV;
2954 LoBound = -(RangeSize - 1);
2955 HiBound = RangeSize;
2956 }
else if (
C.isStrictlyPositive()) {
2958 HiOverflow = LoOverflow = ProdOV;
2964 LoOverflow = HiOverflow = ProdOV ? -1 : 0;
2966 APInt DivNeg = -RangeSize;
2967 LoOverflow =
addWithOverflow(LoBound, HiBound, DivNeg,
true) ? -1 : 0;
2975 LoBound = RangeSize + 1;
2976 HiBound = -RangeSize;
2977 if (HiBound == *C2) {
2981 }
else if (
C.isStrictlyPositive()) {
2984 HiOverflow = LoOverflow = ProdOV ? -1 : 0;
2990 LoOverflow = HiOverflow = ProdOV;
3003 if (LoOverflow && HiOverflow)
3007 X, ConstantInt::get(Ty, LoBound));
3010 X, ConstantInt::get(Ty, HiBound));
3014 if (LoOverflow && HiOverflow)
3018 X, ConstantInt::get(Ty, LoBound));
3021 X, ConstantInt::get(Ty, HiBound));
3026 if (LoOverflow == +1)
3028 if (LoOverflow == -1)
3030 return new ICmpInst(Pred,
X, ConstantInt::get(Ty, LoBound));
3033 if (HiOverflow == +1)
3035 if (HiOverflow == -1)
3077 bool HasNSW =
Sub->hasNoSignedWrap();
3078 bool HasNUW =
Sub->hasNoUnsignedWrap();
3080 ((Cmp.isUnsigned() && HasNUW) || (Cmp.isSigned() && HasNSW)) &&
3082 return new ICmpInst(SwappedPred,
Y, ConstantInt::get(Ty, SubResult));
3090 if (Cmp.isEquality() &&
C.isZero() &&
3091 none_of((
Sub->users()), [](
const User *U) { return isa<PHINode>(U); }))
3099 if (!
Sub->hasOneUse())
3102 if (
Sub->hasNoSignedWrap()) {
3126 (*C2 & (
C - 1)) == (
C - 1))
3139 return new ICmpInst(SwappedPred,
Add, ConstantInt::get(Ty, ~
C));
3145 auto FoldConstant = [&](
bool Val) {
3146 Constant *Res = Val ? Builder.getTrue() : Builder.getFalse();
3153 switch (
Table.to_ulong()) {
3155 return FoldConstant(
false);
3157 return HasOneUse ? Builder.CreateNot(Builder.CreateOr(Op0, Op1)) :
nullptr;
3159 return HasOneUse ? Builder.CreateAnd(Builder.CreateNot(Op0), Op1) :
nullptr;
3161 return Builder.CreateNot(Op0);
3163 return HasOneUse ? Builder.CreateAnd(Op0, Builder.CreateNot(Op1)) :
nullptr;
3165 return Builder.CreateNot(Op1);
3167 return Builder.CreateXor(Op0, Op1);
3169 return HasOneUse ? Builder.CreateNot(Builder.CreateAnd(Op0, Op1)) :
nullptr;
3171 return Builder.CreateAnd(Op0, Op1);
3173 return HasOneUse ? Builder.CreateNot(Builder.CreateXor(Op0, Op1)) :
nullptr;
3177 return HasOneUse ? Builder.CreateOr(Builder.CreateNot(Op0), Op1) :
nullptr;
3181 return HasOneUse ? Builder.CreateOr(Op0, Builder.CreateNot(Op1)) :
nullptr;
3183 return Builder.CreateOr(Op0, Op1);
3185 return FoldConstant(
true);
3200 Cmp.getType() !=
A->getType() || Cmp.getType() !=
B->getType())
3203 std::bitset<4>
Table;
3204 auto ComputeTable = [&](
bool First,
bool Second) -> std::optional<bool> {
3208 auto *Val = Res->getType()->isVectorTy() ? Res->getSplatValue() : Res;
3212 return std::nullopt;
3215 for (
unsigned I = 0;
I < 4; ++
I) {
3216 bool First = (
I >> 1) & 1;
3217 bool Second =
I & 1;
3218 if (
auto Res = ComputeTable(
First, Second))
3240 const APInt *ShAmtC;
3248 return new ICmpInst(Pred,
A, ConstantInt::get(
A->getType(),
C));
3260 if (
Add->hasNoUnsignedWrap() &&
3263 APInt NewC =
C.usub_ov(*C2, Overflow);
3267 return new ICmpInst(Pred,
X, ConstantInt::get(Ty, NewC));
3272 if (
Add->hasNoSignedWrap() &&
3275 APInt NewC =
C.ssub_ov(*C2, Overflow);
3279 return new ICmpInst(ChosenPred,
X, ConstantInt::get(Ty, NewC));
3283 C.isNonNegative() && (
C - *C2).isNonNegative() &&
3286 .isAllNonNegative())
3288 ConstantInt::get(Ty,
C - *C2));
3293 if (Cmp.isSigned()) {
3294 if (
Lower.isSignMask())
3296 if (
Upper.isSignMask())
3299 if (
Lower.isMinValue())
3301 if (
Upper.isMinValue())
3334 if (!
Add->hasOneUse())
3349 ConstantInt::get(Ty,
C * 2));
3363 Builder.CreateAdd(
X, ConstantInt::get(Ty, *C2 -
C - 1)),
3364 ConstantInt::get(Ty, ~
C));
3369 Type *NewCmpTy = V->getType();
3371 if (shouldChangeType(Ty, NewCmpTy)) {
3382 :
Builder.CreateAdd(V, ConstantInt::get(NewCmpTy, EquivOffset)),
3383 ConstantInt::get(NewCmpTy, EquivInt));
3405 Value *EqualVal =
SI->getTrueValue();
3406 Value *UnequalVal =
SI->getFalseValue();
3429 auto FlippedStrictness =
3431 if (!FlippedStrictness)
3434 "basic correctness failure");
3435 RHS2 = FlippedStrictness->second;
3447 assert(
C &&
"Cmp RHS should be a constant int!");
3453 Value *OrigLHS, *OrigRHS;
3454 ConstantInt *C1LessThan, *C2Equal, *C3GreaterThan;
3455 if (Cmp.hasOneUse() &&
3458 assert(C1LessThan && C2Equal && C3GreaterThan);
3461 C1LessThan->
getValue(),
C->getValue(), Cmp.getPredicate());
3463 Cmp.getPredicate());
3465 C3GreaterThan->
getValue(),
C->getValue(), Cmp.getPredicate());
3476 if (TrueWhenLessThan)
3482 if (TrueWhenGreaterThan)
3497 Value *Op1 = Cmp.getOperand(1);
3498 Value *BCSrcOp = Bitcast->getOperand(0);
3499 Type *SrcType = Bitcast->getSrcTy();
3500 Type *DstType = Bitcast->getType();
3504 if (SrcType->isVectorTy() == DstType->isVectorTy() &&
3505 SrcType->getScalarSizeInBits() == DstType->getScalarSizeInBits()) {
3520 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(), 1));
3547 Type *XType =
X->getType();
3550 if (!(XType->
isPPC_FP128Ty() || SrcType->isPPC_FP128Ty())) {
3565 Type *FPType = SrcType->getScalarType();
3566 if (!Cmp.getParent()->getParent()->hasFnAttribute(
3567 Attribute::NoImplicitFloat) &&
3568 Cmp.isEquality() && FPType->isIEEELikeFPTy()) {
3574 Builder.createIsFPClass(BCSrcOp, Mask));
3581 if (!
match(Cmp.getOperand(1),
m_APInt(
C)) || !DstType->isIntegerTy() ||
3582 !SrcType->isIntOrIntVectorTy())
3592 if (Cmp.isEquality() &&
C->isAllOnes() && Bitcast->hasOneUse()) {
3593 if (
Value *NotBCSrcOp =
3595 Value *Cast =
Builder.CreateBitCast(NotBCSrcOp, DstType);
3604 if (Cmp.isEquality() &&
C->isZero() && Bitcast->hasOneUse() &&
3607 Type *NewType =
Builder.getIntNTy(VecTy->getPrimitiveSizeInBits());
3627 if (
C->isSplat(EltTy->getBitWidth())) {
3633 Value *Extract =
Builder.CreateExtractElement(Vec, Mask[0]);
3634 Value *NewC = ConstantInt::get(EltTy,
C->trunc(EltTy->getBitWidth()));
3635 return new ICmpInst(Pred, Extract, NewC);
3673 if (
match(Cmp.getOperand(0),
3679 bool ValidPred =
true;
3697 X->getType()->getScalarType()->getFltSemantics();
3700 if (!Exp.isNegative() && Exp.sle(MaxExp + 1) &&
3702 int ExpVal =
static_cast<int>(Exp.getSExtValue());
3707 ConstantFP::get(
X->getType(), CmpConst));
3716 Value *Cmp0 = Cmp.getOperand(0);
3718 if (
C->isZero() && Cmp.isEquality() && Cmp0->
hasOneUse() &&
3725 return new ICmpInst(Cmp.getPredicate(),
X,
Y);
3740 if (!Cmp.isEquality())
3749 case Instruction::SRem:
3760 case Instruction::Add: {
3767 }
else if (
C.isZero()) {
3770 if (
Value *NegVal = dyn_castNegVal(BOp1))
3771 return new ICmpInst(Pred, BOp0, NegVal);
3772 if (
Value *NegVal = dyn_castNegVal(BOp0))
3773 return new ICmpInst(Pred, NegVal, BOp1);
3782 return new ICmpInst(Pred, BOp0, Neg);
3787 case Instruction::Xor:
3792 }
else if (
C.isZero()) {
3794 return new ICmpInst(Pred, BOp0, BOp1);
3797 case Instruction::Or: {
3818 Cond->getType() == Cmp.getType()) {
3856 case Instruction::UDiv:
3857 case Instruction::SDiv:
3867 return new ICmpInst(Pred, BOp0, BOp1);
3870 Instruction::Mul, BO->
getOpcode() == Instruction::SDiv, BOp1,
3871 Cmp.getOperand(1), BO);
3875 return new ICmpInst(Pred, YC, BOp0);
3879 if (BO->
getOpcode() == Instruction::UDiv &&
C.isZero()) {
3882 return new ICmpInst(NewPred, BOp1, BOp0);
3896 "Non-ctpop intrin in ctpop fold");
3931 Type *Ty =
II->getType();
3935 switch (
II->getIntrinsicID()) {
3936 case Intrinsic::abs:
3939 if (
C.isZero() ||
C.isMinSignedValue())
3940 return new ICmpInst(Pred,
II->getArgOperand(0), ConstantInt::get(Ty,
C));
3943 case Intrinsic::bswap:
3945 return new ICmpInst(Pred,
II->getArgOperand(0),
3946 ConstantInt::get(Ty,
C.byteSwap()));
3948 case Intrinsic::bitreverse:
3950 return new ICmpInst(Pred,
II->getArgOperand(0),
3951 ConstantInt::get(Ty,
C.reverseBits()));
3953 case Intrinsic::ctlz:
3954 case Intrinsic::cttz: {
3957 return new ICmpInst(Pred,
II->getArgOperand(0),
3963 unsigned Num =
C.getLimitedValue(
BitWidth);
3965 bool IsTrailing =
II->getIntrinsicID() == Intrinsic::cttz;
3968 APInt Mask2 = IsTrailing
3972 ConstantInt::get(Ty, Mask2));
3977 case Intrinsic::ctpop: {
3980 bool IsZero =
C.isZero();
3982 return new ICmpInst(Pred,
II->getArgOperand(0),
3989 case Intrinsic::fshl:
3990 case Intrinsic::fshr:
3991 if (
II->getArgOperand(0) ==
II->getArgOperand(1)) {
3992 const APInt *RotAmtC;
3996 return new ICmpInst(Pred,
II->getArgOperand(0),
3997 II->getIntrinsicID() == Intrinsic::fshl
3998 ? ConstantInt::get(Ty,
C.rotr(*RotAmtC))
3999 : ConstantInt::get(Ty,
C.rotl(*RotAmtC)));
4003 case Intrinsic::umax:
4004 case Intrinsic::uadd_sat: {
4007 if (
C.isZero() &&
II->hasOneUse()) {
4014 case Intrinsic::ssub_sat:
4019 if (
C.isZero() &&
II->getType()->getScalarSizeInBits() > 1)
4020 return new ICmpInst(Pred,
II->getArgOperand(0),
II->getArgOperand(1));
4022 case Intrinsic::usub_sat: {
4027 return new ICmpInst(NewPred,
II->getArgOperand(0),
II->getArgOperand(1));
4042 assert(Cmp.isEquality());
4045 Value *Op0 = Cmp.getOperand(0);
4046 Value *Op1 = Cmp.getOperand(1);
4049 if (!IIOp0 || !IIOp1 || IIOp0->getIntrinsicID() != IIOp1->getIntrinsicID())
4052 switch (IIOp0->getIntrinsicID()) {
4053 case Intrinsic::bswap:
4054 case Intrinsic::bitreverse:
4057 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
4058 case Intrinsic::fshl:
4059 case Intrinsic::fshr: {
4062 if (IIOp0->getOperand(0) != IIOp0->getOperand(1))
4064 if (IIOp1->getOperand(0) != IIOp1->getOperand(1))
4066 if (IIOp0->getOperand(2) == IIOp1->getOperand(2))
4067 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
4073 const unsigned BW = IIOp0->getType()->getScalarSizeInBits();
4074 unsigned OneUses = IIOp0->hasOneUse() + IIOp1->hasOneUse();
4083 Builder.CreateSub(IIOp0->getOperand(2), IIOp1->getOperand(2));
4084 Value *CombinedRotate = Builder.CreateIntrinsic(
4085 Op0->
getType(), IIOp0->getIntrinsicID(),
4086 {IIOp0->getOperand(0), IIOp0->getOperand(0), SubAmt});
4087 return new ICmpInst(Pred, IIOp1->getOperand(0), CombinedRotate);
4106 switch (
II->getIntrinsicID()) {
4109 case Intrinsic::fshl:
4110 case Intrinsic::fshr:
4111 if (Cmp.isEquality() &&
II->getArgOperand(0) ==
II->getArgOperand(1)) {
4113 if (
C.isZero() ||
C.isAllOnes())
4114 return new ICmpInst(Pred,
II->getArgOperand(0), Cmp.getOperand(1));
4128 case Instruction::Xor:
4132 case Instruction::And:
4136 case Instruction::Or:
4140 case Instruction::Mul:
4144 case Instruction::Shl:
4148 case Instruction::LShr:
4149 case Instruction::AShr:
4153 case Instruction::SRem:
4157 case Instruction::UDiv:
4161 case Instruction::SDiv:
4165 case Instruction::Sub:
4169 case Instruction::Add:
4193 if (!
II->hasOneUse())
4209 Value *Op0 =
II->getOperand(0);
4210 Value *Op1 =
II->getOperand(1);
4219 switch (
II->getIntrinsicID()) {
4222 "This function only works with usub_sat and uadd_sat for now!");
4223 case Intrinsic::uadd_sat:
4226 case Intrinsic::usub_sat:
4236 II->getBinaryOp(), *COp1,
II->getNoWrapKind());
4243 if (
II->getBinaryOp() == Instruction::Add)
4249 SatValCheck ? Instruction::BinaryOps::Or : Instruction::BinaryOps::And;
4251 std::optional<ConstantRange> Combination;
4252 if (CombiningOp == Instruction::BinaryOps::Or)
4264 Combination->getEquivalentICmp(EquivPred, EquivInt, EquivOffset);
4268 Builder.CreateAdd(Op0, ConstantInt::get(Op1->
getType(), EquivOffset)),
4269 ConstantInt::get(Op1->
getType(), EquivInt));
4276 std::optional<ICmpInst::Predicate> NewPredicate = std::nullopt;
4281 NewPredicate = Pred;
4285 else if (
C.isAllOnes())
4293 else if (
C.isZero())
4310 if (!
C.isZero() && !
C.isAllOnes())
4321 if (
I->getIntrinsicID() == Intrinsic::scmp)
4335 switch (
II->getIntrinsicID()) {
4338 case Intrinsic::uadd_sat:
4339 case Intrinsic::usub_sat:
4344 case Intrinsic::ctpop: {
4349 case Intrinsic::scmp:
4350 case Intrinsic::ucmp:
4356 if (Cmp.isEquality())
4359 Type *Ty =
II->getType();
4361 switch (
II->getIntrinsicID()) {
4362 case Intrinsic::ctpop: {
4374 case Intrinsic::ctlz: {
4377 unsigned Num =
C.getLimitedValue();
4380 II->getArgOperand(0), ConstantInt::get(Ty, Limit));
4385 unsigned Num =
C.getLimitedValue();
4388 II->getArgOperand(0), ConstantInt::get(Ty, Limit));
4392 case Intrinsic::cttz: {
4394 if (!
II->hasOneUse())
4401 Builder.CreateAnd(
II->getArgOperand(0), Mask),
4409 Builder.CreateAnd(
II->getArgOperand(0), Mask),
4414 case Intrinsic::ssub_sat:
4421 return new ICmpInst(Pred,
II->getArgOperand(0),
II->getArgOperand(1));
4425 II->getArgOperand(1));
4429 II->getArgOperand(1));
4432 case Intrinsic::abs: {
4433 if (!
II->hasOneUse())
4442 Builder.CreateAdd(
X, ConstantInt::get(Ty,
C)),
4443 ConstantInt::get(Ty, 2 *
C));
4450 Builder.CreateAdd(
X, ConstantInt::get(Ty,
C - 1)),
4451 ConstantInt::get(Ty, 2 * (
C - 1)));
4464 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
4471 case Instruction::IntToPtr:
4476 APInt NullPtrValue =
4484 case Instruction::Load:
4501 auto SimplifyOp = [&](
Value *
Op,
bool SelectCondIsTrue) ->
Value * {
4505 SI->getCondition(), Pred,
Op, RHS,
DL, SelectCondIsTrue))
4506 return ConstantInt::get(
I.getType(), *Impl);
4511 Value *Op1 = SimplifyOp(
SI->getOperand(1),
true);
4515 Value *Op2 = SimplifyOp(
SI->getOperand(2),
false);
4519 auto Simplifies = [&](
Value *
Op,
unsigned Idx) {
4534 bool Transform =
false;
4537 else if (Simplifies(Op1, 1) || Simplifies(Op2, 2)) {
4539 if (
SI->hasOneUse())
4542 else if (CI && !CI->
isZero())
4550 Op1 =
Builder.CreateICmp(Pred,
SI->getOperand(1), RHS,
I.getName());
4552 Op2 =
Builder.CreateICmp(Pred,
SI->getOperand(2), RHS,
I.getName());
4563 const APInt *C1, *C2, *
P;
4570 if (C1SatisfiesCond && !C2SatisfiesCond) {
4574 Value *Cmp2 =
Builder.CreateICmp(Pred, RHS,
SI->getFalseValue());
4576 return BinaryOperator::CreateOr(Cmp1, Cmp2);
4577 return BinaryOperator::CreateAnd(Cmp1, Cmp2);
4587 unsigned Depth = 0) {
4590 if (V->getType()->getScalarSizeInBits() == 1)
4598 switch (
I->getOpcode()) {
4599 case Instruction::ZExt:
4602 case Instruction::SExt:
4606 case Instruction::And:
4607 case Instruction::Or:
4614 case Instruction::Xor:
4624 case Instruction::Select:
4628 case Instruction::Shl:
4631 case Instruction::LShr:
4634 case Instruction::AShr:
4638 case Instruction::Add:
4644 case Instruction::Sub:
4650 case Instruction::Call: {
4652 switch (
II->getIntrinsicID()) {
4655 case Intrinsic::umax:
4656 case Intrinsic::smax:
4657 case Intrinsic::umin:
4658 case Intrinsic::smin:
4663 case Intrinsic::bitreverse:
4753 auto IsLowBitMask = [&]() {
4771 auto Check = [&]() {
4789 auto Check = [&]() {
4808 if (!IsLowBitMask())
4827 const APInt *C0, *C1;
4844 const APInt &MaskedBits = *C0;
4845 assert(MaskedBits != 0 &&
"shift by zero should be folded away already.");
4866 auto *XType =
X->getType();
4867 const unsigned XBitWidth = XType->getScalarSizeInBits();
4869 assert(
BitWidth.ugt(MaskedBits) &&
"shifts should leave some bits untouched");
4882 Value *T0 = Builder.CreateAdd(
X, ConstantInt::get(XType, AddCst));
4884 Value *
T1 = Builder.CreateICmp(DstPred, T0, ConstantInt::get(XType, ICmpCst));
4900 !
I.getOperand(0)->hasOneUse())
4925 assert(NarrowestTy ==
I.getOperand(0)->getType() &&
4926 "We did not look past any shifts while matching XShift though.");
4927 bool HadTrunc = WidestTy !=
I.getOperand(0)->getType();
4934 auto XShiftOpcode = XShift->
getOpcode();
4935 if (XShiftOpcode == YShift->
getOpcode())
4938 Value *
X, *XShAmt, *
Y, *YShAmt;
4947 if (!
match(
I.getOperand(0),
4973 unsigned MaximalPossibleTotalShiftAmount =
4976 APInt MaximalRepresentableShiftAmount =
4978 if (MaximalRepresentableShiftAmount.
ult(MaximalPossibleTotalShiftAmount))
4987 if (NewShAmt->getType() != WidestTy) {
4997 if (!
match(NewShAmt,
4999 APInt(WidestBitWidth, WidestBitWidth))))
5004 auto CanFold = [NewShAmt, WidestBitWidth, NarrowestShift, SQ,
5010 ? NewShAmt->getSplatValue()
5013 if (NewShAmtSplat &&
5021 unsigned MinLeadZero =
Known.countMinLeadingZeros();
5023 unsigned MaxActiveBits =
Known.getBitWidth() - MinLeadZero;
5024 if (MaxActiveBits <= 1)
5032 unsigned MinLeadZero =
Known.countMinLeadingZeros();
5034 unsigned MaxActiveBits =
Known.getBitWidth() - MinLeadZero;
5035 if (MaxActiveBits <= 1)
5038 if (NewShAmtSplat) {
5041 if (AdjNewShAmt.
ule(MinLeadZero))
5052 X = Builder.CreateZExt(
X, WidestTy);
5053 Y = Builder.CreateZExt(
Y, WidestTy);
5055 Value *T0 = XShiftOpcode == Instruction::BinaryOps::LShr
5056 ? Builder.CreateLShr(
X, NewShAmt)
5057 : Builder.CreateShl(
X, NewShAmt);
5058 Value *
T1 = Builder.CreateAnd(T0,
Y);
5059 return Builder.CreateICmp(
I.getPredicate(),
T1,
5077 if (!
I.isEquality() &&
5087 NeedNegation =
false;
5090 NeedNegation =
true;
5096 if (
I.isEquality() &&
5111 bool MulHadOtherUses =
Mul && !
Mul->hasOneUse();
5112 if (MulHadOtherUses)
5116 Div->
getOpcode() == Instruction::UDiv ? Intrinsic::umul_with_overflow
5117 : Intrinsic::smul_with_overflow,
5118 X->getType(), {X, Y},
nullptr,
"mul");
5123 if (MulHadOtherUses)
5128 Res =
Builder.CreateNot(Res,
"mul.not.ov");
5132 if (MulHadOtherUses)
5158 Type *Ty =
X->getType();
5162 Value *
And = Builder.CreateAnd(
X, MaxSignedVal);
5172 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5234 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5269 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5285 return new ICmpInst(PredOut, Op0, Op1);
5305 return new ICmpInst(NewPred, Op0, Const);
5317 if (!
C.isPowerOf2())
5330 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5345 Value *Dividend, *Divisor;
5346 if (
I.isEquality() &&
5351 return new ICmpInst(NewPred, Dividend, Divisor);
5410 return new ICmpInst(NewPred, Op1, Zero);
5419 return new ICmpInst(NewPred, Op0, Zero);
5423 bool NoOp0WrapProblem =
false, NoOp1WrapProblem =
false;
5424 bool Op0HasNUW =
false, Op1HasNUW =
false;
5425 bool Op0HasNSW =
false, Op1HasNSW =
false;
5429 bool &HasNSW,
bool &HasNUW) ->
bool {
5436 }
else if (BO.
getOpcode() == Instruction::Or) {
5446 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr;
5450 NoOp0WrapProblem = hasNoWrapProblem(*BO0, Pred, Op0HasNSW, Op0HasNUW);
5454 NoOp1WrapProblem = hasNoWrapProblem(*BO1, Pred, Op1HasNSW, Op1HasNUW);
5459 if ((
A == Op1 ||
B == Op1) && NoOp0WrapProblem)
5465 if ((
C == Op0 ||
D == Op0) && NoOp1WrapProblem)
5470 if (
A &&
C && (
A ==
C ||
A ==
D ||
B ==
C ||
B ==
D) && NoOp0WrapProblem &&
5478 }
else if (
A ==
D) {
5482 }
else if (
B ==
C) {
5499 bool IsNegative) ->
bool {
5500 const APInt *OffsetC;
5512 if (!
C.isStrictlyPositive())
5539 if (
A && NoOp0WrapProblem && IsAddOrSignedPred &&
5540 ShareCommonDivisor(
A, Op1,
B, IsNegative))
5550 if (
C && NoOp1WrapProblem &&
5551 ShareCommonDivisor(Op0,
C,
D,
5564 if (
A &&
C && NoOp0WrapProblem && NoOp1WrapProblem &&
5566 const APInt *AP1, *AP2;
5574 if (AP1Abs.
uge(AP2Abs)) {
5575 APInt Diff = *AP1 - *AP2;
5578 A, C3,
"", Op0HasNUW && Diff.
ule(*AP1), Op0HasNSW);
5581 APInt Diff = *AP2 - *AP1;
5584 C, C3,
"", Op1HasNUW && Diff.
ule(*AP2), Op1HasNSW);
5603 if (BO0 && BO0->
getOpcode() == Instruction::Sub) {
5607 if (BO1 && BO1->
getOpcode() == Instruction::Sub) {
5613 if (
A == Op1 && NoOp0WrapProblem)
5616 if (
C == Op0 && NoOp1WrapProblem)
5636 if (
B &&
D &&
B ==
D && NoOp0WrapProblem && NoOp1WrapProblem)
5640 if (
A &&
C &&
A ==
C && NoOp0WrapProblem && NoOp1WrapProblem)
5648 if (RHSC->isNotMinSignedValue())
5649 return new ICmpInst(
I.getSwappedPredicate(),
X,
5667 if (Op0HasNSW && Op1HasNSW) {
5674 SQ.getWithInstruction(&
I));
5679 SQ.getWithInstruction(&
I));
5680 if (GreaterThan &&
match(GreaterThan,
m_One()))
5687 if (((Op0HasNSW && Op1HasNSW) || (Op0HasNUW && Op1HasNUW)) &&
5699 if (NonZero && BO0 && BO1 && Op0HasNSW && Op1HasNSW)
5706 if (NonZero && BO0 && BO1 && Op0HasNUW && Op1HasNUW)
5717 else if (BO1 && BO1->
getOpcode() == Instruction::SRem &&
5747 case Instruction::Add:
5748 case Instruction::Sub:
5749 case Instruction::Xor: {
5756 if (
C->isSignMask()) {
5762 if (BO0->
getOpcode() == Instruction::Xor &&
C->isMaxSignedValue()) {
5764 NewPred =
I.getSwappedPredicate(NewPred);
5770 case Instruction::Mul: {
5771 if (!
I.isEquality())
5779 if (
unsigned TZs =
C->countr_zero()) {
5785 return new ICmpInst(Pred, And1, And2);
5790 case Instruction::UDiv:
5791 case Instruction::LShr:
5796 case Instruction::SDiv:
5802 case Instruction::AShr:
5807 case Instruction::Shl: {
5808 bool NUW = Op0HasNUW && Op1HasNUW;
5809 bool NSW = Op0HasNSW && Op1HasNSW;
5812 if (!NSW &&
I.isSigned())
5876 auto IsCondKnownTrue = [](
Value *Val) -> std::optional<bool> {
5878 return std::nullopt;
5883 return std::nullopt;
5889 Pred = Pred.dropSameSign();
5892 if (!CmpXZ.has_value() && !CmpYZ.has_value())
5894 if (!CmpXZ.has_value()) {
5900 if (CmpYZ.has_value())
5924 if (!MinMaxCmpXZ.has_value()) {
5932 if (!MinMaxCmpXZ.has_value())
5948 return FoldIntoCmpYZ();
5975 return FoldIntoCmpYZ();
5984 return FoldIntoCmpYZ();
6016 const APInt *
Lo =
nullptr, *
Hi =
nullptr;
6039 I,
Builder.CreateICmp(Pred,
X, ConstantInt::get(
X->getType(),
C)));
6045 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6049 if (
I.isEquality()) {
6084 Type *Ty =
A->getType();
6085 Value *CtPop = Builder.CreateUnaryIntrinsic(Intrinsic::ctpop,
A);
6087 ConstantInt::get(Ty, 2))
6089 ConstantInt::get(Ty, 1));
6096using OffsetOp = std::pair<Instruction::BinaryOps, Value *>;
6098 bool AllowRecursion) {
6104 case Instruction::Add:
6105 Offsets.emplace_back(Instruction::Sub, Inst->
getOperand(1));
6106 Offsets.emplace_back(Instruction::Sub, Inst->
getOperand(0));
6108 case Instruction::Sub:
6109 Offsets.emplace_back(Instruction::Add, Inst->
getOperand(1));
6111 case Instruction::Xor:
6112 Offsets.emplace_back(Instruction::Xor, Inst->
getOperand(1));
6113 Offsets.emplace_back(Instruction::Xor, Inst->
getOperand(0));
6115 case Instruction::Shl:
6117 Offsets.emplace_back(Instruction::AShr, Inst->
getOperand(1));
6119 Offsets.emplace_back(Instruction::LShr, Inst->
getOperand(1));
6121 case Instruction::Select:
6122 if (AllowRecursion) {
6169 assert(
I.isEquality() &&
"Expected an equality icmp");
6170 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6181 case Instruction::AShr: {
6182 const APInt *CV, *CRHS;
6184 CV->
ashr(*CRHS).
shl(*CRHS) == *CV) &&
6190 case Instruction::LShr: {
6191 const APInt *CV, *CRHS;
6193 CV->
lshr(*CRHS).
shl(*CRHS) == *CV) &&
6212 auto ApplyOffset = [&](
Value *V,
unsigned BinOpc,
6215 if (!Sel->hasOneUse())
6217 Value *TrueVal = ApplyOffsetImpl(Sel->getTrueValue(), BinOpc,
RHS);
6220 Value *FalseVal = ApplyOffsetImpl(Sel->getFalseValue(), BinOpc,
RHS);
6225 if (
Value *Simplified = ApplyOffsetImpl(V, BinOpc,
RHS))
6230 for (
auto [BinOp,
RHS] : OffsetOps) {
6231 auto BinOpc =
static_cast<unsigned>(BinOp);
6233 auto Op0Result = ApplyOffset(Op0, BinOpc,
RHS);
6234 if (!Op0Result.isValid())
6236 auto Op1Result = ApplyOffset(Op1, BinOpc,
RHS);
6237 if (!Op1Result.isValid())
6240 Value *NewLHS = Op0Result.materialize(Builder);
6241 Value *NewRHS = Op1Result.materialize(Builder);
6242 return new ICmpInst(
I.getPredicate(), NewLHS, NewRHS);
6249 if (!
I.isEquality())
6252 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6256 if (
A == Op1 ||
B == Op1) {
6257 Value *OtherVal =
A == Op1 ?
B :
A;
6285 Value *OtherVal =
A == Op0 ?
B :
A;
6292 Value *
X =
nullptr, *
Y =
nullptr, *Z =
nullptr;
6298 }
else if (
A ==
D) {
6302 }
else if (
B ==
C) {
6306 }
else if (
B ==
D) {
6316 const APInt *C0, *C1;
6318 (*C0 ^ *C1).isNegatedPowerOf2();
6324 int(Op0->
hasOneUse()) + int(Op1->hasOneUse()) +
6326 if (XorIsNegP2 || UseCnt >= 2) {
6329 Op1 =
Builder.CreateAnd(Op1, Z);
6349 (Op0->
hasOneUse() || Op1->hasOneUse())) {
6354 MaskC->
countr_one() ==
A->getType()->getScalarSizeInBits())
6360 const APInt *AP1, *AP2;
6369 if (ShAmt < TypeBits && ShAmt != 0) {
6374 return new ICmpInst(NewPred,
Xor, ConstantInt::get(
A->getType(), CmpVal));
6384 if (ShAmt < TypeBits && ShAmt != 0) {
6404 if (ShAmt < ASize) {
6427 A->getType()->getScalarSizeInBits() ==
BitWidth * 2 &&
6428 (
I.getOperand(0)->hasOneUse() ||
I.getOperand(1)->hasOneUse())) {
6433 Add, ConstantInt::get(
A->getType(),
C.shl(1)));
6460 Builder.CreateIntrinsic(Op0->
getType(), Intrinsic::fshl, {A, A, B}));
6475 std::optional<bool> IsZero = std::nullopt;
6517 Constant *
C = ConstantInt::get(Res->X->getType(), Res->C);
6521 unsigned SrcBits =
X->getType()->getScalarSizeInBits();
6523 if (
II->getIntrinsicID() == Intrinsic::cttz ||
6524 II->getIntrinsicID() == Intrinsic::ctlz) {
6525 unsigned MaxRet = SrcBits;
6551 bool IsSignedExt = CastOp0->getOpcode() == Instruction::SExt;
6552 bool IsSignedCmp = ICmp.
isSigned();
6560 if (IsZext0 != IsZext1) {
6565 if (ICmp.
isEquality() &&
X->getType()->isIntOrIntVectorTy(1) &&
6566 Y->getType()->isIntOrIntVectorTy(1))
6576 bool IsNonNeg0 = NonNegInst0 && NonNegInst0->hasNonNeg();
6577 bool IsNonNeg1 = NonNegInst1 && NonNegInst1->hasNonNeg();
6579 if ((IsZext0 && IsNonNeg0) || (IsZext1 && IsNonNeg1))
6586 Type *XTy =
X->getType(), *YTy =
Y->getType();
6593 IsSignedExt ? Instruction::SExt : Instruction::ZExt;
6595 X =
Builder.CreateCast(CastOpcode,
X, YTy);
6597 Y =
Builder.CreateCast(CastOpcode,
Y, XTy);
6609 if (IsSignedCmp && IsSignedExt)
6622 Type *SrcTy = CastOp0->getSrcTy();
6630 if (IsSignedExt && IsSignedCmp)
6661 Value *SimplifiedOp0 = simplifyIntToPtrRoundTripCast(ICmp.
getOperand(0));
6662 Value *SimplifiedOp1 = simplifyIntToPtrRoundTripCast(ICmp.
getOperand(1));
6663 if (SimplifiedOp0 || SimplifiedOp1)
6665 SimplifiedOp0 ? SimplifiedOp0 : ICmp.
getOperand(0),
6666 SimplifiedOp1 ? SimplifiedOp1 : ICmp.
getOperand(1));
6675 Value *Op0Src = CastOp0->getOperand(0);
6676 Type *SrcTy = CastOp0->getSrcTy();
6677 Type *DestTy = CastOp0->getDestTy();
6681 auto CompatibleSizes = [&](
Type *PtrTy,
Type *IntTy) {
6682 unsigned IntWidth = IntTy->getScalarType()->getIntegerBitWidth();
6683 unsigned IndexWidth =
DL.getAddressSizeInBits(PtrTy);
6684 unsigned PtrWidth =
DL.getPointerTypeSizeInBits(PtrTy);
6687 return IntWidth == IndexWidth && IndexWidth == PtrWidth;
6691 Value *NewOp1 =
nullptr;
6693 NewOp1 = PtrToIntOp1->getOperand(0);
6696 NewOp1 = PtrToAddrOp1->getOperand(0);
6703 if ((!HasPtrToInt || CompatibleSizes(SrcTy, DestTy)) &&
6709 if (CastOp0->getOpcode() == Instruction::IntToPtr &&
6710 CompatibleSizes(DestTy, SrcTy)) {
6711 Value *NewOp1 =
nullptr;
6713 Value *IntSrc = IntToPtrOp1->getOperand(0);
6715 NewOp1 = IntToPtrOp1->getOperand(0);
6735 case Instruction::Add:
6736 case Instruction::Sub:
6738 case Instruction::Mul:
6739 return !(
RHS->getType()->isIntOrIntVectorTy(1) && IsSigned) &&
6751 case Instruction::Add:
6756 case Instruction::Sub:
6761 case Instruction::Mul:
6770 bool IsSigned,
Value *LHS,
6781 Builder.SetInsertPoint(&OrigI);
6798 Result = Builder.CreateBinOp(BinaryOp,
LHS,
RHS);
6799 Result->takeName(&OrigI);
6803 Result = Builder.CreateBinOp(BinaryOp,
LHS,
RHS);
6804 Result->takeName(&OrigI);
6808 Inst->setHasNoSignedWrap();
6810 Inst->setHasNoUnsignedWrap();
6835 const APInt *OtherVal,
6843 unsigned Opcode = Instr->getOpcode();
6844 assert(Opcode == Instruction::Add || Opcode == Instruction::Mul);
6851 Type *TyA =
A->getType(), *TyB =
B->getType();
6853 WidthB = TyB->getPrimitiveSizeInBits();
6854 unsigned ResultWidth;
6856 if (WidthB > WidthA) {
6857 ResultWidth = WidthB;
6860 ResultWidth = WidthA;
6873 unsigned TruncWidth = TI->getType()->getPrimitiveSizeInBits();
6874 if (TruncWidth > ResultWidth)
6878 if (BO->getOpcode() != Instruction::And)
6881 const APInt &CVal = CI->getValue();
6897 switch (
I.getPredicate()) {
6904 if (MaxVal.
eq(*OtherVal))
6914 if (MaxVal.
eq(*OtherVal))
6927 Value *ResultA =
A, *ResultB =
B;
6928 if (WidthA < ResultWidth)
6929 ResultA = Builder.CreateZExt(
A, ResultType);
6930 if (WidthB < ResultWidth)
6931 ResultB = Builder.CreateZExt(
B, ResultType);
6934 Value *OverflowCheck;
6936 if (Opcode == Instruction::Add) {
6938 ArithResult = Builder.CreateAdd(ResultA, ResultB,
"add");
6942 Builder.CreateICmpUGE(ArithResult, ResultA,
"not.add.overflow");
6945 Builder.CreateICmpULT(ArithResult, ResultA,
"add.overflow");
6948 Value *
Call = Builder.CreateIntrinsic(Intrinsic::umul_with_overflow,
6949 ResultType, {ResultA, ResultB},
6951 ArithResult = Builder.CreateExtractValue(
Call, 0,
"umul.value");
6952 OverflowCheck = Builder.CreateExtractValue(
Call, 1,
"umul.overflow");
6954 OverflowCheck = Builder.CreateNot(OverflowCheck);
6965 if (TI->getType()->getPrimitiveSizeInBits() == ResultWidth)
6970 assert(BO->getOpcode() == Instruction::And);
6974 Value *ShortAnd = Builder.CreateAnd(ArithResult, ShortMask);
6975 Value *Zext = Builder.CreateZExt(ShortAnd, BO->
getType());
7001 switch (
I.getPredicate()) {
7032 assert(DI && UI &&
"Instruction not defined\n");
7044 if (Usr != UI && !
DT.dominates(DB, Usr->getParent()))
7059 if (!IC || (IC->getOperand(0) !=
SI && IC->getOperand(1) !=
SI))
7106 const unsigned SIOpd) {
7107 assert((SIOpd == 1 || SIOpd == 2) &&
"Invalid select operand!");
7109 BasicBlock *Succ =
SI->getParent()->getTerminator()->getSuccessor(1);
7123 SI->replaceUsesOutsideBlock(
SI->getOperand(SIOpd),
SI->getParent());
7133 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7138 unsigned BitWidth = Ty->isIntOrIntVectorTy()
7139 ? Ty->getScalarSizeInBits()
7140 :
DL.getPointerTypeSizeInBits(Ty->getScalarType());
7164 if (
I.hasSameSign() &&
I.isUnsigned()) {
7166 if (To.isNegative() || To.isNonNegative())
7171 To.makeNonNegative();
7173 PropagateSignBit(Op0Known, Op1Known);
7174 PropagateSignBit(Op1Known, Op0Known);
7209 if (!Cmp.hasOneUse())
7218 if (!isMinMaxCmp(
I)) {
7223 if (Op1Min == Op0Max)
7228 if (*CmpC == Op0Min + 1)
7230 ConstantInt::get(Op1->getType(), *CmpC - 1));
7240 if (Op1Max == Op0Min)
7245 if (*CmpC == Op0Max - 1)
7247 ConstantInt::get(Op1->getType(), *CmpC + 1));
7257 if (Op1Min == Op0Max)
7261 if (*CmpC == Op0Min + 1)
7263 ConstantInt::get(Op1->getType(), *CmpC - 1));
7268 if (Op1Max == Op0Min)
7272 if (*CmpC == Op0Max - 1)
7274 ConstantInt::get(Op1->getType(), *CmpC + 1));
7291 APInt Op0KnownZeroInverted = ~Op0Known.Zero;
7294 Value *LHS =
nullptr;
7297 *LHSC != Op0KnownZeroInverted)
7303 Type *XTy =
X->getType();
7305 APInt C2 = Op0KnownZeroInverted;
7306 APInt C2Pow2 = (C2 & ~(*C1 - 1)) + *C1;
7312 auto *CmpC = ConstantInt::get(XTy, Log2C2 - Log2C1);
7322 (Op0Known & Op1Known) == Op0Known)
7328 if (Op1Min == Op0Max)
7332 if (Op1Max == Op0Min)
7336 if (Op1Min == Op0Max)
7340 if (Op1Max == Op0Min)
7348 if ((
I.isSigned() || (
I.isUnsigned() && !
I.hasSameSign())) &&
7351 I.setPredicate(
I.getUnsignedPredicate());
7369 return BinaryOperator::CreateAnd(
Builder.CreateIsNull(
X),
Y);
7375 return BinaryOperator::CreateOr(
Builder.CreateIsNull(
X),
Y);
7386 bool IsSExt = ExtI->
getOpcode() == Instruction::SExt;
7388 auto CreateRangeCheck = [&] {
7403 }
else if (!IsSExt || HasOneUse) {
7408 return CreateRangeCheck();
7410 }
else if (IsSExt ?
C->isAllOnes() :
C->isOne()) {
7418 }
else if (!IsSExt || HasOneUse) {
7423 return CreateRangeCheck();
7437 Instruction::ICmp, Pred1,
X,
7456 Value *Op0 =
I.getOperand(0);
7457 Value *Op1 =
I.getOperand(1);
7463 if (!FlippedStrictness)
7467 new ICmpInst(FlippedStrictness->first, Op0, FlippedStrictness->second);
7468 NewCmp->setSameSign(FlippedStrictness->first.hasSameSign());
7487 I.setName(
I.getName() +
".not");
7498 Value *
A =
I.getOperand(0), *
B =
I.getOperand(1);
7499 assert(
A->getType()->isIntOrIntVectorTy(1) &&
"Bools only");
7505 switch (
I.getPredicate()) {
7514 switch (
I.getPredicate()) {
7524 switch (
I.getPredicate()) {
7533 return BinaryOperator::CreateXor(
A,
B);
7541 return BinaryOperator::CreateAnd(Builder.CreateNot(
A),
B);
7549 return BinaryOperator::CreateAnd(Builder.CreateNot(
B),
A);
7557 return BinaryOperator::CreateOr(Builder.CreateNot(
A),
B);
7565 return BinaryOperator::CreateOr(Builder.CreateNot(
B),
A);
7613 Value *NewX = Builder.CreateLShr(
X,
Y,
X->getName() +
".highbits");
7621 Value *
LHS = Cmp.getOperand(0), *
RHS = Cmp.getOperand(1);
7625 Value *V = Builder.CreateCmp(Pred,
X,
Y, Cmp.getName());
7627 I->copyIRFlags(&Cmp);
7628 Module *M = Cmp.getModule();
7630 M, Intrinsic::vector_reverse, V->getType());
7637 (
LHS->hasOneUse() ||
RHS->hasOneUse()))
7638 return createCmpReverse(Pred,
V1, V2);
7642 return createCmpReverse(Pred,
V1,
RHS);
7646 return createCmpReverse(Pred,
LHS, V2);
7655 Type *V1Ty =
V1->getType();
7657 V1Ty == V2->
getType() && (
LHS->hasOneUse() ||
RHS->hasOneUse())) {
7658 Value *NewCmp = Builder.CreateCmp(Pred,
V1, V2);
7671 Constant *ScalarC =
C->getSplatValue(
true);
7679 Value *NewCmp = Builder.CreateCmp(Pred,
V1,
C);
7690 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7696 if (
match(Op0, UAddOvResultPat) &&
7707 (Op0 ==
A || Op0 ==
B))
7717 if (!
I.getOperand(0)->getType()->isPointerTy() ||
7719 I.getParent()->getParent(),
7720 I.getOperand(0)->getType()->getPointerAddressSpace())) {
7724 if (
match(
I.getOperand(0),
7740 Value *Const =
I.getOperand(1);
7758 Type *VecEltTy = VecTy->getElementType();
7760 DL.getTypeSizeInBits(VecEltTy) * VecTy->getNumElements();
7761 if (!
DL.fitsInLegalInteger(ScalarBW))
7765 ? ConstantInt::get(ScalarTy, 0)
7768 Builder.CreateBitCast(Vec, ScalarTy), NewConst);
7780 if (
I.getType()->isVectorTy())
7803 if (!LHSTy || !LHSTy->getElementType()->isIntegerTy())
7806 LHSTy->getNumElements() * LHSTy->getElementType()->getIntegerBitWidth();
7808 if (!
DL.isLegalInteger(NumBits))
7812 auto *ScalarTy = Builder.getIntNTy(NumBits);
7813 LHS = Builder.CreateBitCast(
LHS, ScalarTy,
LHS->getName() +
".scalar");
7814 RHS = Builder.CreateBitCast(
RHS, ScalarTy,
RHS->getName() +
".scalar");
7870 bool IsIntMinPosion =
C->isAllOnesValue();
7882 CtxI, IsIntMinPosion
7883 ?
Builder.CreateICmpSGT(
X, AllOnesValue)
7885 X, ConstantInt::get(
X->getType(),
SMin + 1)));
7891 CtxI, IsIntMinPosion
7892 ?
Builder.CreateICmpSLT(
X, NullValue)
7894 X, ConstantInt::get(
X->getType(),
SMin)));
7921 auto CheckUGT1 = [](
const APInt &Divisor) {
return Divisor.ugt(1); };
7936 auto CheckNE0 = [](
const APInt &Shift) {
return !Shift.isZero(); };
7957 if (ShAmt >=
X->getType()->getScalarSizeInBits())
7959 if (canEvaluateShifted(Op1, ShAmt,
false,
7961 Value *NewOp1 = getShiftedValue(Op1, ShAmt,
false,
7969 if (ShAmt >=
X->getType()->getScalarSizeInBits())
7971 if (canEvaluateShifted(Op1, ShAmt,
false,
7973 Value *NewOp1 = getShiftedValue(Op1, ShAmt,
false,
7984 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7991 if (Op0Cplxity < Op1Cplxity) {
8006 if (
Value *V = dyn_castNegVal(SelectTrue)) {
8007 if (V == SelectFalse)
8009 }
else if (
Value *V = dyn_castNegVal(SelectFalse)) {
8010 if (V == SelectTrue)
8070 if (
C->isNonNegative())
8074 ConstantInt::get(
X->getType(), ~*
C));
8080 if (
C->isNonNegative())
8084 ConstantInt::get(
X->getType(), ~*
C));
8140 if (
I.isCommutative()) {
8141 if (
auto Pair = matchSymmetricPair(
I.getOperand(0),
I.getOperand(1))) {
8170 (Op0->
hasOneUse() || Op1->hasOneUse())) {
8198 bool I0NUW = I0->hasNoUnsignedWrap();
8199 bool I1NUW = I1->hasNoUnsignedWrap();
8200 bool I0NSW = I0->hasNoSignedWrap();
8201 bool I1NSW = I1->hasNoSignedWrap();
8205 ((I0NUW || I0NSW) && (I1NUW || I1NSW)))) {
8207 ConstantInt::get(Op0->
getType(), 0));
8214 assert(Op1->getType()->isPointerTy() &&
8215 "Comparing pointer with non-pointer?");
8244 bool ConsumesOp0, ConsumesOp1;
8247 (ConsumesOp0 || ConsumesOp1)) {
8250 assert(InvOp0 && InvOp1 &&
8251 "Mismatch between isFreeToInvert and getFreelyInverted");
8252 return new ICmpInst(
I.getSwappedPredicate(), InvOp0, InvOp1);
8264 if (AddI->
getOpcode() == Instruction::Add &&
8265 OptimizeOverflowCheck(Instruction::Add,
false,
X,
Y, *AddI,
8266 Result, Overflow)) {
8286 if ((
I.isUnsigned() ||
I.isEquality()) &&
8289 Y->getType()->getScalarSizeInBits() == 1 &&
8290 (Op0->
hasOneUse() || Op1->hasOneUse())) {
8297 unsigned ShiftOpc = ShiftI->
getOpcode();
8298 if ((ExtOpc == Instruction::ZExt && ShiftOpc == Instruction::LShr) ||
8299 (ExtOpc == Instruction::SExt && ShiftOpc == Instruction::AShr)) {
8333 if (EVI->getIndices()[0] == 0 && ACXI->getCompareOperand() == Op1 &&
8340 if (
I.getType()->isVectorTy())
8352 const APInt *C1, *C2;
8359 Type *InputTy =
A->getType();
8366 TruncC1.
setBit(InputBitWidth - 1);
8370 ConstantInt::get(InputTy, C2->
trunc(InputBitWidth)));
8390 if (MantissaWidth == -1)
8397 if (
I.isEquality()) {
8399 bool IsExact =
false;
8400 APSInt RHSCvt(IntWidth, LHSUnsigned);
8409 if (*RHS != RHSRoundInt) {
8429 if ((
int)IntWidth > MantissaWidth) {
8431 int Exp =
ilogb(*RHS);
8434 if (MaxExponent < (
int)IntWidth - !LHSUnsigned)
8440 if (MantissaWidth <= Exp && Exp <= (
int)IntWidth - !LHSUnsigned)
8449 assert(!RHS->isNaN() &&
"NaN comparison not already folded!");
8452 switch (
I.getPredicate()) {
8543 APSInt RHSInt(IntWidth, LHSUnsigned);
8546 if (!RHS->isZero()) {
8561 if (RHS->isNegative())
8567 if (RHS->isNegative())
8573 if (RHS->isNegative())
8580 if (!RHS->isNegative())
8586 if (RHS->isNegative())
8592 if (RHS->isNegative())
8598 if (RHS->isNegative())
8605 if (!RHS->isNegative())
8624 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
8635 unsigned Pred =
I.getPredicate();
8643 if (!Res00 || !Res01 || !Res10 || !Res11)
8652 std::bitset<4>
Table;
8710 if (
C->isNegative())
8711 Pred =
I.getSwappedPredicate();
8738 "X ord/uno NaN should be folded away by simplifyFCmpInst()");
8744 bool RoundDown =
false;
8765 auto NextValue = [](
const APFloat &
Value,
bool RoundDown) {
8767 NextValue.
next(RoundDown);
8771 APFloat NextCValue = NextValue(*CValue, RoundDown);
8776 APFloat ExtCValue = ConvertFltSema(*CValue, DestFltSema);
8777 APFloat ExtNextCValue = ConvertFltSema(NextCValue, DestFltSema);
8784 APFloat PrevCValue = NextValue(*CValue, !RoundDown);
8785 APFloat Bias = ConvertFltSema(*CValue - PrevCValue, DestFltSema);
8787 ExtNextCValue = ExtCValue + Bias;
8794 C.getType()->getScalarType()->getFltSemantics();
8797 APFloat MidValue = ConvertFltSema(ExtMidValue, SrcFltSema);
8798 if (MidValue != *CValue)
8799 ExtMidValue.
next(!RoundDown);
8807 if (ConvertFltSema(ExtMidValue, SrcFltSema).isInfinity())
8811 APFloat NextExtMidValue = NextValue(ExtMidValue, RoundDown);
8812 if (ConvertFltSema(NextExtMidValue, SrcFltSema).
isFinite())
8817 ConstantFP::get(DestType, ExtMidValue),
"", &
I);
8830 if (!
C->isPosZero()) {
8831 if (!
C->isSmallestNormalized())
8844 switch (
I.getPredicate()) {
8870 switch (
I.getPredicate()) {
8895 assert(!
I.hasNoNaNs() &&
"fcmp should have simplified");
8900 assert(!
I.hasNoNaNs() &&
"fcmp should have simplified");
8914 return replacePredAndOp0(&
I,
I.getPredicate(),
X);
8937 I.setHasNoInfs(
false);
8939 switch (
I.getPredicate()) {
8984 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
8989 Pred =
I.getSwappedPredicate();
8998 return new FCmpInst(Pred, Op0, Zero,
"", &
I);
9034 I.getFunction()->getDenormalMode(
9041 I.setHasNoNaNs(
true);
9066 if (MantissaWidth != -1 &&
ilogb(*
C) < MantissaWidth) {
9068 I.setPredicate(
I.getSwappedPredicate());
9105 if (!IsStrictLt && !IsStrictGt && !IsGe)
9127 }
else if (
match(FAbsArg,
9135 if (
A->getType() !=
B->getType())
9150 Type *OpType =
LHS->getType();
9156 if (!FloorX && !CeilX) {
9160 Pred =
I.getSwappedPredicate();
9236 if (!
I || !(
I->getOpcode() == Instruction::SIToFP ||
9237 I->getOpcode() == Instruction::UIToFP))
9240 bool IsUnsigned =
I->getOpcode() == Instruction::UIToFP;
9241 unsigned BitWidth =
I->getOperand(0)->getType()->getScalarSizeInBits();
9264 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
9266 SQ.getWithInstruction(&
I)))
9271 assert(OpType == Op1->getType() &&
"fcmp with different-typed operands?");
9296 if (
I.isCommutative()) {
9297 if (
auto Pair = matchSymmetricPair(
I.getOperand(0),
I.getOperand(1))) {
9319 return new FCmpInst(
I.getSwappedPredicate(),
X,
Y,
"", &
I);
9335 bool IsRedundantMinMaxClamp =
9397 X->getType()->isIntOrIntVectorTy() &&
9398 !
F.getDenormalMode(Op1->getType()->getScalarType()->getFltSemantics())
9399 .inputsMayBeZero()) {
9407 Type *IntTy =
X->getType();
9408 const APInt &SignMask =
~APInt::getSignMask(IntTy->getScalarSizeInBits());
9409 Value *MaskX =
Builder.CreateAnd(
X, ConstantInt::get(IntTy, SignMask));
9419 case Instruction::Select:
9427 case Instruction::FSub:
9432 case Instruction::PHI:
9436 case Instruction::SIToFP:
9437 case Instruction::UIToFP:
9441 case Instruction::FDiv:
9445 case Instruction::Load:
9451 case Instruction::FPTrunc:
9478 return new FCmpInst(
I.getSwappedPredicate(),
X, NegC,
"", &
I);
9492 X->getType() ==
Y->getType())
9503 X->getType()->getScalarType()->getFltSemantics();
9539 Constant *NewC = ConstantFP::get(
X->getType(), TruncC);
9552 Type *IntType =
Builder.getIntNTy(
X->getType()->getScalarSizeInBits());
9565 Value *CanonLHS =
nullptr;
9568 if (CanonLHS == Op1)
9569 return new FCmpInst(Pred, Op1, Op1,
"", &
I);
9571 Value *CanonRHS =
nullptr;
9574 if (CanonRHS == Op0)
9575 return new FCmpInst(Pred, Op0, Op0,
"", &
I);
9578 if (CanonLHS && CanonRHS)
9579 return new FCmpInst(Pred, CanonLHS, CanonRHS,
"", &
I);
9582 if (
I.getType()->isVectorTy())
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
This file declares a class to represent arbitrary precision floating point values and provide a varie...
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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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 void collectOffsetOp(Value *V, SmallVectorImpl< OffsetOp > &Offsets, bool AllowRecursion)
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 isMinMaxCmpSelectEliminable(SelectPatternFlavor Flavor, Value *A, Value *B)
Returns true if a select that implements a min/max is redundant and select result can be replaced wit...
static Instruction * foldICmpEqualityWithOffset(ICmpInst &I, InstCombiner::BuilderTy &Builder, const SimplifyQuery &SQ)
Offset both sides of an equality icmp to see if we can save some instructions: icmp eq/ne X,...
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 * foldICmpOfVectorReduce(ICmpInst &I, const DataLayout &DL, IRBuilderBase &Builder)
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)
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
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 * processUZExtIdiom(ICmpInst &I, Value *Val, const APInt *OtherVal, InstCombinerImpl &IC)
Recognize and process idiom involving test for unsigned overflow.
static Instruction * foldICmpOfCmpIntrinsicWithConstant(CmpPredicate Pred, IntrinsicInst *I, const APInt &C, InstCombiner::BuilderTy &Builder)
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 * foldFCmpFpTrunc(FCmpInst &I, const Instruction &FPTrunc, const Constant &C)
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 Instruction * foldFCmpFAbsFSubIntToFP(FCmpInst &I, InstCombinerImpl &IC)
Fold: fabs(uitofp(a) - uitofp(b)) pred C --> a == b where 'pred' is olt, ult, ogt,...
static void setInsertionPoint(IRBuilder<> &Builder, Value *V, bool Before=true)
static bool isNeutralValue(Instruction::BinaryOps BinaryOp, Value *RHS, bool IsSigned)
static bool isMultipleOf(Value *X, const APInt &C, const SimplifyQuery &Q)
Return true if X is a multiple of C.
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.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
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 TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static SymbolRef::Type getType(const Symbol *Sym)
cmpResult
IEEE-754R 5.11: Floating Point Comparison Relations.
static constexpr roundingMode rmTowardZero
static constexpr roundingMode rmNearestTiesToEven
static LLVM_ABI ExponentType semanticsMaxExponent(const fltSemantics &)
opStatus
IEEE-754R 7: Default exception handling.
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
static APFloat getOne(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative One.
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.
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
opStatus next(bool nextDown)
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
LLVM_ABI FPClassTest classify() const
Return the FPClassTest which will return true for the value.
opStatus roundToIntegral(roundingMode RM)
Class for arbitrary precision integers.
LLVM_ABI 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 LLVM_ABI 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.
LLVM_ABI 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.
LLVM_ABI 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.
LLVM_ABI 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.
LLVM_ABI APInt sadd_ov(const APInt &RHS, bool &Overflow) const
bool eq(const APInt &RHS) const
Equality comparison.
LLVM_ABI APInt sdiv(const APInt &RHS) const
Signed division function for APInt.
LLVM_ABI 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.
void flipAllBits()
Toggle every bit to its opposite value.
unsigned countl_one() const
Count the number of leading one bits.
unsigned logBase2() const
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
bool isMaxSignedValue() const
Determine if this is the largest signed value.
bool ule(const APInt &RHS) const
Unsigned less or equal comparison.
APInt shl(unsigned shiftAmt) const
Left-shift function.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
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.
LLVM_ABI 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.
static APSInt getMinValue(uint32_t numBits, bool Unsigned)
Return the APSInt representing the minimum integer value with the given bit width and signedness.
static APSInt getMaxValue(uint32_t numBits, bool Unsigned)
Return the APSInt representing the maximum integer value with the given bit width and signedness.
an instruction to allocate memory on the stack
Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
LLVM_ABI 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; assumes that the block is well-formed.
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
static LLVM_ABI 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.
Value * getArgOperand(unsigned i) const
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
This class is the base class for the comparison instructions.
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate getStrictPredicate() const
For example, SGE -> SGT, SLE -> SLT, ULE -> ULT, UGE -> UGT.
bool isEquality() const
Determine if this is an equals/not equals predicate.
static LLVM_ABI Predicate getFlippedStrictnessPredicate(Predicate pred)
This is a static version that you can use without an instruction available.
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)
static LLVM_ABI bool isEquality(Predicate pred)
Determine if this is an equals/not equals predicate.
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 LLVM_ABI 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.
static LLVM_ABI bool isStrictPredicate(Predicate predicate)
This is a static version that you can use without an instruction available.
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.
static bool isIntPredicate(Predicate P)
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
static LLVM_ABI CmpPredicate getSwapped(CmpPredicate P)
Get the swapped predicate of a CmpPredicate.
Conditional Branch instruction.
static LLVM_ABI Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getPointerBitCastOrAddrSpaceCast(Constant *C, Type *Ty)
Create a BitCast or AddrSpaceCast for a pointer type depending on the address space.
static LLVM_ABI Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI Constant * getNot(Constant *C)
static LLVM_ABI Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getXor(Constant *C1, Constant *C2)
static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)
static LLVM_ABI ConstantFP * 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 LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static LLVM_ABI 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 LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)
This class represents a range of values.
LLVM_ABI ConstantRange add(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an addition of a value in this ran...
LLVM_ABI 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...
LLVM_ABI bool getEquivalentICmp(CmpInst::Predicate &Pred, APInt &RHS) const
Set up Pred and RHS such that ConstantRange::makeExactICmpRegion(Pred, RHS) == *this.
LLVM_ABI 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.
LLVM_ABI ConstantRange difference(const ConstantRange &CR) const
Subtract the specified range from this range (aka relative complement of the sets).
LLVM_ABI bool isEmptySet() const
Return true if this set contains no members.
LLVM_ABI ConstantRange truncate(uint32_t BitWidth, unsigned NoWrapKind=0) const
Return a new range in the specified integer type, which must be strictly smaller than the current typ...
static LLVM_ABI 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...
LLVM_ABI ConstantRange inverse() const
Return a new range that is the logical not of the current set.
LLVM_ABI 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...
LLVM_ABI ConstantRange intersectWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the intersection of this range with another range.
static ConstantRange getNonEmpty(APInt Lower, APInt Upper)
Create non-empty constant range with the given bounds.
LLVM_ABI 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 LLVM_ABI 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 LLVM_ABI 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 LLVM_ABI 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...
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
LLVM_ABI bool isAllOnesValue() const
Return true if this is the value that would be returned by getAllOnesValue.
LLVM_ABI const APInt & getUniqueInteger() const
If C is a constant integer then return its value, otherwise C must be a vector of constant integers,...
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
iterator find(const_arg_type_t< KeyT > Val)
This instruction compares its operands according to the predicate given to the constructor.
static bool isCommutative(Predicate Pred)
static bool isEquality(Predicate Pred)
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.
LLVM_ABI 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
This instruction compares its operands according to the predicate given to the constructor.
static bool isGE(Predicate P)
Return true if the predicate is SGE or UGE.
static LLVM_ABI bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
static bool isLT(Predicate P)
Return true if the predicate is SLT or ULT.
static bool isGT(Predicate P)
Return true if the predicate is SGT or UGT.
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.
static bool isLE(Predicate P)
Return true if the predicate is SLE or ULE.
Common base class shared among various IRBuilders.
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
ConstantInt * getInt(const APInt &AI)
Get a constant integer value.
LLVM_ABI Value * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *Op, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 1 operand which is mangled on its type.
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 * 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 * foldCmpLoadFromIndexedGlobal(LoadInst *LI, GetElementPtrInst *GEP, 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 * foldICmpSubConstant(ICmpInst &Cmp, BinaryOperator *Sub, const APInt &C)
Fold icmp (sub X, Y), C.
Instruction * foldICmpWithClamp(ICmpInst &Cmp, Value *X, MinMaxIntrinsic *Min)
Match and fold patterns like: icmp eq/ne X, min(max(X, Lo), Hi) which represents a range check and ca...
Instruction * foldICmpInstWithConstantNotInt(ICmpInst &Cmp)
Handle icmp with constant (but not simple integer constant) RHS.
bool SimplifyDemandedBits(Instruction *I, unsigned Op, const APInt &DemandedMask, KnownBits &Known, const SimplifyQuery &Q, unsigned Depth=0) override
This form of SimplifyDemandedBits simplifies the specified instruction operand if possible,...
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.
Instruction * FoldOpIntoSelect(Instruction &Op, SelectInst *SI, bool FoldWithMultiUse=false, bool SimplifyBothArms=false)
Given an instruction with a select as one operand and a constant as the other operand,...
Value * foldMultiplicationOverflowCheck(ICmpInst &Cmp)
Fold (-1 u/ x) u< y ((x * y) ?
Instruction * foldICmpWithConstant(ICmpInst &Cmp)
Fold icmp Pred X, C.
OverflowResult computeOverflow(Instruction::BinaryOps BinaryOp, bool IsSigned, Value *LHS, Value *RHS, Instruction *CtxI) const
CmpInst * canonicalizeICmpPredicate(CmpInst &I)
If we have a comparison with a non-canonical predicate, if we can update all the users,...
Instruction * eraseInstFromFunction(Instruction &I) override
Combiner aware instruction erasure.
Instruction * foldICmpWithZero(ICmpInst &Cmp)
Instruction * foldICmpBinOpEqualityWithConstant(ICmpInst &Cmp, BinaryOperator *BO, const APInt &C)
Fold an icmp equality instruction with binary operator LHS and constant RHS: icmp eq/ne BO,...
Instruction * foldICmpUsingBoolRange(ICmpInst &I)
If one operand of an icmp is effectively a bool (value range of {0,1}), then try to reduce patterns b...
Instruction * foldICmpWithTrunc(ICmpInst &Cmp)
Instruction * foldCmpSelectOfConstants(CmpInst &I)
Fold fcmp/icmp pred (select C1, TV1, FV1), (select C2, TV2, FV2) where all true/false values are cons...
Instruction * foldICmpIntrinsicWithConstant(ICmpInst &ICI, IntrinsicInst *II, const APInt &C)
Fold an icmp with LLVM intrinsic and constant operand: icmp Pred II, C.
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,...
const InstCombineCLOptions & CLOpts
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".
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 * foldICmpCommutative(CmpPredicate Pred, Value *Op0, Value *Op1, ICmpInst &CtxI)
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 * foldIsMultipleOfAPowerOfTwo(ICmpInst &Cmp)
Fold icmp eq (num + mask) & ~mask, num to icmp eq (and num, mask), 0 Where mask is a low bit mask.
Instruction * foldICmpAndShift(ICmpInst &Cmp, BinaryOperator *And, const APInt &C1, const APInt &C2)
Fold icmp (and (sh X, Y), C2), C1.
Instruction * foldICmpBinOpWithConstantViaTruthTable(ICmpInst &Cmp, BinaryOperator *BO, const APInt &C)
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)
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 computeOverflowForSignedMul(const Value *LHS, const Value *RHS, const Instruction *CtxI) const
LLVM_ABI bool canBeCastedExactlyIntToFP(Value *V, Type *FPTy, bool IsSigned, const Instruction *CtxI=nullptr) const
bool isFreeToInvert(Value *V, bool WillInvertAllUses, bool &DoesConsume)
Return true if the specified value is free to invert (apply ~ to).
static unsigned getComplexity(Value *V)
Assign a complexity or rank value to LLVM Values.
unsigned ComputeMaxSignificantBits(const Value *Op, const Instruction *CtxI=nullptr, unsigned Depth=0) const
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, const Instruction *CtxI=nullptr, unsigned Depth=0)
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
static Constant * SubOne(Constant *C)
Subtract one from a Constant.
OverflowResult computeOverflowForUnsignedSub(const Value *LHS, const Value *RHS, const Instruction *CtxI) const
static bool isCanonicalPredicate(CmpPredicate Pred)
Predicate canonicalization reduces the number of patterns that need to be matched by other transforms...
IRBuilder< TargetFolder, IRBuilderInstCombineInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
bool canFreelyInvertAllUsersOf(Instruction *V, Value *IgnoredUser)
Given i1 V, can every user of V be freely adapted if V is changed to !V ?
OverflowResult computeOverflowForSignedAdd(const WithCache< const Value * > &LHS, const WithCache< const Value * > &RHS, const Instruction *CtxI) const
void addToWorklist(Instruction *I)
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
OverflowResult computeOverflowForUnsignedMul(const Value *LHS, const Value *RHS, const Instruction *CtxI, bool IsNSW=false) const
OverflowResult computeOverflowForSignedSub(const Value *LHS, const Value *RHS, const Instruction *CtxI) const
OverflowResult computeOverflowForUnsignedAdd(const WithCache< const Value * > &LHS, const WithCache< const Value * > &RHS, const Instruction *CtxI) const
void computeKnownBits(const Value *V, KnownBits &Known, const Instruction *CtxI, unsigned Depth=0) const
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
const SimplifyQuery & getSimplifyQuery() const
LLVM_ABI bool hasNoNaNs() const LLVM_READONLY
Determine whether the no-NaNs flag is set.
LLVM_ABI bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
LLVM_ABI 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.
LLVM_ABI bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
LLVM_ABI bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
LLVM_ABI bool isExact() const LLVM_READONLY
Determine whether the exact flag is set.
iterator_range< user_iterator > users()
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
static LLVM_ABI 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.
static bool isMin(Intrinsic::ID ID)
Whether the intrinsic is a smin or umin.
static bool isSigned(Intrinsic::ID ID)
Whether the intrinsic is signed or unsigned.
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, const Instruction *MDFrom=nullptr)
A vector that has set insertion semantics.
size_type size() const
Determine the number of elements in the SetVector.
bool contains(const_arg_type key) const
Check if the SetVector contains the given key.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This instruction constructs a fixed permutation of two input vectors.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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.
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.
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.
LLVM_ABI 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.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
LLVM_ABI int getFPMantissaWidth() const
Return the width of the mantissa of this type.
LLVM_ABI const fltSemantics & getFltSemantics() const
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.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< user_iterator > users()
LLVM_ABI bool hasNUsesOrMore(unsigned N) const
Return true if this value has N uses or more.
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
iterator_range< use_iterator > uses()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
const ParentTy * getParent() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI APInt RoundingUDiv(const APInt &A, const APInt &B, APInt::Rounding RM)
Return A unsign-divided by B, rounded by the given rounding mode.
LLVM_ABI APInt RoundingSDiv(const APInt &A, const APInt &B, APInt::Rounding RM)
Return A sign-divided by B, rounded by the given rounding mode.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
auto m_PosZeroFP()
Matches a floating-point positive zero.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
AllOnesConstantMatch m_AllOnes()
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
match_unless< Pattern > m_Unless(const Pattern &P)
Match if the inner matcher does NOT match.
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
match_combine_and< Ty... > m_CombineAnd(const Ty &...Ps)
Combine pattern matchers matching all of Ps patterns.
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)
cst_pred_ty< is_negative > m_Negative()
Match an integer or vector of negative values.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
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)
BinaryOp_match< LHS, RHS, Instruction::FSub > m_FSub(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)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
auto m_Sqrt(const Opnd0 &Op0)
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
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.
match_bind< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
match_deferred< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
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)
ap_match< APFloat > m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
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< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap, true > m_c_NUWAdd(const LHS &L, const RHS &R)
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.
auto m_SMax(const Opnd0 &Op0, const Opnd1 &Op1)
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
auto m_BinOp()
Match an arbitrary binary operation and ignore it.
auto m_UMax(const Opnd0 &Op0, const Opnd1 &Op1)
ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)
Match a single index ExtractValue instruction.
BinOpPred_match< LHS, RHS, is_logical_shift_op > m_LogicalShift(const LHS &L, const RHS &R)
Matches logical shift operations.
match_combine_or< CastInst_match< OpTy, UIToFPInst >, CastInst_match< OpTy, SIToFPInst > > m_IToFP(const OpTy &Op)
auto m_Value()
Match an arbitrary value and ignore it.
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)
auto m_Constant()
Match an arbitrary Constant and ignore it.
NoWrapTrunc_match< OpTy, TruncInst::NoSignedWrap > m_NSWTrunc(const OpTy &Op)
Matches trunc nsw.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
cst_pred_ty< is_non_zero_int > m_NonZeroInt()
Match a non-zero integer or a vector with all non-zero elements.
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)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoSignedWrap > m_NSWShl(const LHS &L, const RHS &R)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWShl(const LHS &L, const RHS &R)
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)
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
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.
SelectLike_match< CondTy, LTy, RTy > m_SelectLike(const CondTy &C, const LTy &TrueC, const RTy &FalseC)
Matches a value that behaves like a boolean-controlled select, i.e.
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.
cstfp_pred_ty< is_finitenonzero > m_FiniteNonZero()
Match a finite non-zero FP constant.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)
auto m_SMin(const Opnd0 &Op0, const Opnd1 &Op1)
auto m_FAbs(const Opnd0 &Op0)
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'.
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.
BinOpPred_match< LHS, RHS, is_irem_op > m_IRem(const LHS &L, const RHS &R)
Matches integer remainder operations.
auto m_MaxOrMin(const Opnd0 &Op0, const Opnd1 &Op1)
CastInst_match< OpTy, FPTruncInst > m_FPTrunc(const OpTy &Op)
auto m_Undef()
Match an arbitrary undef constant.
auto m_VecReverse(const Opnd0 &Op0)
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)
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)
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.
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
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.
LLVM_ABI bool isKnownNeverInfinity(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point scalar value is not an infinity or if the floating-point vector val...
LLVM_ABI 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.
@ Known
Known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ BinaryOp
One of the operands is a binary op.
LLVM_ABI Value * stripNullTest(Value *V)
Returns the inner value X if the expression has the form f(X) where f(X) == 0 if and only if X == 0,...
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
LLVM_ABI Value * simplifyFCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q)
Given operands for an FCmpInst, fold the result or return null.
int ilogb(const APFloat &Arg)
Returns the exponent of the internal representation of the APFloat.
LLVM_ABI bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Return true if the given value is known to have exactly one bit set when defined.
LLVM_ABI bool MaskedValueIsZero(const Value *V, const APInt &Mask, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if 'V & Mask' is known to be zero.
LLVM_ABI Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Function *CtxF=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
LLVM_ABI Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for an Add, fold the result or return null.
LLVM_ABI Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI 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.
LLVM_ABI 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
LLVM_ABI Constant * ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op, const DataLayout &DL)
Attempt to constant fold a unary operation with the specified operand.
LLVM_ABI 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.
@ SPF_FMAXNUM
Floating point minnum.
@ SPF_FMINNUM
Unsigned maximum.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI bool impliesPoison(const Value *ValAssumedPoison, const Value *V)
Return true if V is poison given that ValAssumedPoison is already poison.
LLVM_ABI LinearExpression decomposeLinearExpression(const DataLayout &DL, Value *Ptr)
Decompose a pointer into a linear expression.
LLVM_ABI bool isFinite(const Loop *L)
Return true if this loop can be assumed to run for a finite number of iterations.
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode RM)
Returns: X * 2^Exp for integral exponents.
LLVM_ABI 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...
LLVM_ABI 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.
LLVM_ABI Value * simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an ICmpInst, fold the result or return null.
LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
LLVM_ABI Constant * ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset, const DataLayout &DL)
Extract value of C at the given Offset reinterpreted as Ty.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
LLVM_ABI 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.
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
LLVM_ABI Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
@ UMin
Unsigned integer min implemented in terms of select(cmp()).
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ SMax
Signed integer max implemented in terms of select(cmp()).
@ SMin
Signed integer min implemented in terms of select(cmp()).
@ Sub
Subtraction of integers.
@ UMax
Unsigned integer max implemented in terms of select(cmp()).
LLVM_ABI bool isKnownNonEqual(const Value *V1, const Value *V2, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the given values are known to be non-equal when defined.
DWARFExpression::Operation Op
LLVM_ABI bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, unsigned MaxUsesToExplore=0)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
constexpr unsigned BitWidth
LLVM_ABI Constant * getLosslessInvCast(Constant *C, Type *InvCastTo, unsigned CastOp, const DataLayout &DL, PreservedCastFlags *Flags=nullptr)
Try to cast C to InvC losslessly, satisfying CastOp(InvC) equals C, or CastOp(InvC) is a refined valu...
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...
LLVM_ABI bool isKnownNeverInfOrNaN(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point value can never contain a NaN or infinity.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isKnownNeverNaN(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...
LLVM_ABI std::optional< std::pair< CmpPredicate, Constant * > > getFlippedStrictnessPredicateAndConstant(CmpPredicate Pred, Constant *C)
Convert an integer comparison with a constant RHS into an equivalent form with the strictness flipped...
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
LLVM_ABI bool isKnownPositive(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the given value is known be positive (i.e.
LLVM_ABI bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the give value is known to be non-negative.
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
LLVM_ABI 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.
LLVM_ABI std::optional< DecomposedBitTest > decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate Pred, bool LookThroughTrunc=true, bool AllowNonZeroC=false, bool DecomposeAnd=false)
Decompose an icmp into the form ((X & Mask) pred C) if possible.
LLVM_ABI ConstantRange computeConstantRange(const Value *V, bool ForSigned, const SimplifyQuery &SQ, unsigned Depth=0)
Determine the possible constant range of an integer or vector of integer value.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Value * materialize(InstCombiner::BuilderTy &Builder) const
static OffsetResult select(Value *Cond, Value *TrueV, Value *FalseV, Instruction *MDFrom)
static OffsetResult value(Value *V)
static OffsetResult invalid()
This callback is used in conjunction with PointerMayBeCaptured.
static CommonPointerBase compute(Value *LHS, Value *RHS)
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.
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.
Linear expression BasePtr + Index * Scale + Offset.
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
A MapVector that performs no allocations if smaller than a certain size.
Capture information for a specific Use.