41#define DEBUG_TYPE "instcombine"
49 bool IsSigned =
false) {
52 Result = In1.
sadd_ov(In2, Overflow);
54 Result = In1.
uadd_ov(In2, Overflow);
62 bool IsSigned =
false) {
65 Result = In1.
ssub_ov(In2, Overflow);
67 Result = In1.
usub_ov(In2, Overflow);
75 for (
auto *U :
I.users())
97 }
else if (
C.isAllOnes()) {
124 if (LI->
isVolatile() || !GV || !GV->isConstant() ||
125 !GV->hasDefinitiveInitializer())
129 TypeSize EltSize =
DL.getTypeStoreSize(EltTy);
145 if (!ConstOffset.
ult(Stride))
164 uint64_t ArrayElementCount =
167 if (ArrayElementCount >
CLOpts.maxarray_size)
170 enum { Overdefined = -3, Undefined = -2 };
179 int FirstTrueElement = Undefined, SecondTrueElement = Undefined;
183 int FirstFalseElement = Undefined, SecondFalseElement = Undefined;
191 int TrueRangeEnd = Undefined, FalseRangeEnd = Undefined;
196 uint64_t MagicBitvector = 0;
200 for (
unsigned i = 0, e = ArrayElementCount; i != e; ++i,
Offset += Stride) {
221 if (TrueRangeEnd == (
int)i - 1)
223 if (FalseRangeEnd == (
int)i - 1)
240 if (FirstTrueElement == Undefined)
241 FirstTrueElement = TrueRangeEnd = i;
244 if (SecondTrueElement == Undefined)
245 SecondTrueElement = i;
247 SecondTrueElement = Overdefined;
250 if (TrueRangeEnd == (
int)i - 1)
253 TrueRangeEnd = Overdefined;
257 if (FirstFalseElement == Undefined)
258 FirstFalseElement = FalseRangeEnd = i;
261 if (SecondFalseElement == Undefined)
262 SecondFalseElement = i;
264 SecondFalseElement = Overdefined;
267 if (FalseRangeEnd == (
int)i - 1)
270 FalseRangeEnd = Overdefined;
275 if (i < 64 && IsTrueForElt)
276 MagicBitvector |= 1ULL << i;
281 if ((i & 8) == 0 && i >= 64 && SecondTrueElement == Overdefined &&
282 SecondFalseElement == Overdefined && TrueRangeEnd == Overdefined &&
283 FalseRangeEnd == Overdefined)
297 auto MaskIdx = [&](
Value *Idx) {
301 Idx =
Builder.CreateAnd(Idx, Mask);
308 if (SecondTrueElement != Overdefined) {
311 if (FirstTrueElement == Undefined)
314 Value *FirstTrueIdx = ConstantInt::get(Idx->getType(), FirstTrueElement);
317 if (SecondTrueElement == Undefined)
322 Value *SecondTrueIdx = ConstantInt::get(Idx->getType(), SecondTrueElement);
324 return BinaryOperator::CreateOr(C1, C2);
329 if (SecondFalseElement != Overdefined) {
332 if (FirstFalseElement == Undefined)
335 Value *FirstFalseIdx = ConstantInt::get(Idx->getType(), FirstFalseElement);
338 if (SecondFalseElement == Undefined)
343 Value *SecondFalseIdx =
344 ConstantInt::get(Idx->getType(), SecondFalseElement);
346 return BinaryOperator::CreateAnd(C1, C2);
351 if (TrueRangeEnd != Overdefined) {
352 assert(TrueRangeEnd != FirstTrueElement &&
"Should emit single compare");
356 if (FirstTrueElement) {
358 Idx =
Builder.CreateAdd(Idx, Offs);
362 ConstantInt::get(Idx->getType(), TrueRangeEnd - FirstTrueElement + 1);
367 if (FalseRangeEnd != Overdefined) {
368 assert(FalseRangeEnd != FirstFalseElement &&
"Should emit single compare");
371 if (FirstFalseElement) {
373 Idx =
Builder.CreateAdd(Idx, Offs);
377 ConstantInt::get(Idx->getType(), FalseRangeEnd - FirstFalseElement);
390 if (ArrayElementCount <= Idx->
getType()->getIntegerBitWidth())
393 Ty =
DL.getSmallestLegalIntType(
Init->getContext(), ArrayElementCount);
398 V =
Builder.CreateLShr(ConstantInt::get(Ty, MagicBitvector), V);
399 V =
Builder.CreateAnd(ConstantInt::get(Ty, 1), V);
424 while (!WorkList.
empty()) {
427 while (!WorkList.
empty()) {
428 if (Explored.
size() >= 100)
446 if (!
GEP->isInBounds() ||
count_if(
GEP->indices(), IsNonConst) > 1)
454 if (WorkList.
back() == V) {
470 for (
auto *PN : PHIs)
471 for (
Value *
Op : PN->incoming_values())
479 for (
Value *Val : Explored) {
485 if (Inst ==
Base || Inst ==
PHI || !Inst || !
PHI ||
489 if (
PHI->getParent() == Inst->getParent())
499 bool Before =
true) {
507 I = &*std::next(
I->getIterator());
508 Builder.SetInsertPoint(
I);
513 BasicBlock &Entry =
A->getParent()->getEntryBlock();
514 Builder.SetInsertPoint(Entry.getFirstInsertionPt());
536 Base->getContext(),
DL.getIndexTypeSizeInBits(Start->getType()));
542 for (
Value *Val : Explored) {
550 PHI->getName() +
".idx",
PHI->getIterator());
555 for (
Value *Val : Explored) {
564 NewInsts[
GEP] = OffsetV;
566 NewInsts[
GEP] = Builder.CreateAdd(
567 Op, OffsetV,
GEP->getOperand(0)->getName() +
".add",
579 for (
Value *Val : Explored) {
586 for (
unsigned I = 0,
E =
PHI->getNumIncomingValues();
I <
E; ++
I) {
587 Value *NewIncoming =
PHI->getIncomingValue(
I);
589 auto It = NewInsts.
find(NewIncoming);
590 if (It != NewInsts.
end())
591 NewIncoming = It->second;
598 for (
Value *Val : Explored) {
604 Value *NewVal = Builder.CreateGEP(Builder.getInt8Ty(),
Base, NewInsts[Val],
605 Val->getName() +
".ptr", NW);
612 return NewInsts[Start];
698 if (
Base.Ptr == RHS && CanFold(
Base.LHSNW) && !
Base.isExpensive()) {
702 EmitGEPOffsets(
Base.LHSGEPs,
Base.LHSNW, IdxTy,
true);
710 RHS->getType()->getPointerAddressSpace())) {
741 if (GEPLHS->
getOperand(0) != GEPRHS->getOperand(0)) {
742 bool IndicesTheSame =
745 GEPRHS->getPointerOperand()->getType() &&
749 if (GEPLHS->
getOperand(i) != GEPRHS->getOperand(i)) {
750 IndicesTheSame =
false;
756 if (IndicesTheSame &&
764 if (GEPLHS->
isInBounds() && GEPRHS->isInBounds() &&
766 (GEPRHS->hasAllConstantIndices() || GEPRHS->hasOneUse()) &&
770 Value *LOffset = EmitGEPOffset(GEPLHS);
771 Value *ROffset = EmitGEPOffset(GEPRHS);
778 if (LHSIndexTy != RHSIndexTy) {
781 ROffset =
Builder.CreateTrunc(ROffset, LHSIndexTy);
783 LOffset =
Builder.CreateTrunc(LOffset, RHSIndexTy);
792 if (GEPLHS->
getOperand(0) == GEPRHS->getOperand(0) &&
796 unsigned NumDifferences = 0;
797 unsigned DiffOperand = 0;
798 for (
unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i)
799 if (GEPLHS->
getOperand(i) != GEPRHS->getOperand(i)) {
801 Type *RHSType = GEPRHS->getOperand(i)->getType();
812 if (NumDifferences++)
817 if (NumDifferences == 0)
825 Value *RHSV = GEPRHS->getOperand(DiffOperand);
826 return NewICmp(NW, LHSV, RHSV);
830 if (
Base.Ptr && !
Base.isExpensive()) {
832 bool DoFold = CanFold(
Base.LHSNW &
Base.RHSNW);
834 if (!DoFold &&
Base.Ptr->getType()->isPointerTy()) {
838 unsigned BW =
DL.getIndexTypeSizeInBits(GEPLHS->
getType());
843 DL, LOff,
true) ==
Base.Ptr &&
844 RHS->stripAndAccumulateConstantOffsets(
845 DL, ROff,
true) ==
Base.Ptr)
857 return NewICmp(
Base.LHSNW &
Base.RHSNW, L, R);
884 bool Captured =
false;
889 CmpCaptureTracker(
AllocaInst *Alloca) : Alloca(Alloca) {}
891 void tooManyUses()
override { Captured =
true; }
903 ICmps[ICmp] |= 1u << U->getOperandNo();
912 CmpCaptureTracker Tracker(Alloca);
914 if (Tracker.Captured)
918 for (
auto [ICmp,
Operands] : Tracker.ICmps) {
924 auto *Res = ConstantInt::get(ICmp->getType(),
950 assert(!!
C &&
"C should not be zero!");
966 ConstantInt::get(
X->getType(), -
C));
978 ConstantInt::get(
X->getType(),
SMax -
C));
989 ConstantInt::get(
X->getType(),
SMax - (
C - 1)));
998 assert(
I.isEquality() &&
"Cannot fold icmp gt/lt");
1001 if (
I.getPredicate() ==
I.ICMP_NE)
1003 return new ICmpInst(Pred, LHS, RHS);
1022 return getICmp(
I.ICMP_UGT,
A,
1023 ConstantInt::get(
A->getType(), AP2.
logBase2()));
1035 if (IsAShr && AP1 == AP2.
ashr(Shift)) {
1039 return getICmp(
I.ICMP_UGE,
A, ConstantInt::get(
A->getType(), Shift));
1040 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1041 }
else if (AP1 == AP2.
lshr(Shift)) {
1042 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1048 auto *TorF = ConstantInt::get(
I.getType(),
I.getPredicate() ==
I.ICMP_NE);
1057 assert(
I.isEquality() &&
"Cannot fold icmp gt/lt");
1060 if (
I.getPredicate() ==
I.ICMP_NE)
1062 return new ICmpInst(Pred, LHS, RHS);
1071 if (!AP1 && AP2TrailingZeros != 0)
1074 ConstantInt::get(
A->getType(), AP2.
getBitWidth() - AP2TrailingZeros));
1082 if (Shift > 0 && AP2.
shl(Shift) == AP1)
1083 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1087 auto *TorF = ConstantInt::get(
I.getType(),
I.getPredicate() ==
I.ICMP_NE);
1116 if (NewWidth != 7 && NewWidth != 15 && NewWidth != 31)
1140 if (U == AddWithCst)
1158 I.getModule(), Intrinsic::sadd_with_overflow, NewType);
1166 Value *TruncA = Builder.CreateTrunc(
A, NewType,
A->getName() +
".trunc");
1167 Value *TruncB = Builder.CreateTrunc(
B, NewType,
B->getName() +
".trunc");
1168 CallInst *
Call = Builder.CreateCall(
F, {TruncA, TruncB},
"sadd");
1169 Value *
Add = Builder.CreateExtractValue(
Call, 0,
"sadd.result");
1187 if (!
I.isEquality())
1218 APInt(XBitWidth, XBitWidth - 1))))
1245 return new ICmpInst(Pred,
B, Cmp.getOperand(1));
1247 return new ICmpInst(Pred,
A, Cmp.getOperand(1));
1264 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1276 return new ICmpInst(Pred,
Y, Cmp.getOperand(1));
1282 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1285 if (BO0->hasNoUnsignedWrap() || BO0->hasNoSignedWrap()) {
1293 return new ICmpInst(Pred,
Y, Cmp.getOperand(1));
1298 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1314 return new ICmpInst(Pred, Stripped,
1327 const APInt *Mask, *Neg;
1343 auto *NewAnd =
Builder.CreateAnd(Num, *Mask);
1346 return new ICmpInst(Pred, NewAnd, Zero);
1367 Value *Op0 = Cmp.getOperand(0), *Op1 = Cmp.getOperand(1);
1383 for (
Value *V : Phi->incoming_values()) {
1391 PHINode *NewPhi =
Builder.CreatePHI(Cmp.getType(), Phi->getNumOperands());
1392 for (
auto [V, Pred] :
zip(
Ops, Phi->blocks()))
1407 Value *
X = Cmp.getOperand(0), *
Y = Cmp.getOperand(1);
1440 if (Cmp.isEquality() || (IsSignBit &&
hasBranchUse(Cmp)))
1445 if (Cmp.hasOneUse() &&
1459 if (!
match(BI->getCondition(),
1464 if (
DT.dominates(Edge0, Cmp.getParent())) {
1465 if (
auto *V = handleDomCond(DomPred, DomC))
1469 if (
DT.dominates(Edge1, Cmp.getParent()))
1485 Type *SrcTy =
X->getType();
1487 SrcBits = SrcTy->getScalarSizeInBits();
1491 if (shouldChangeType(Trunc->
getType(), SrcTy)) {
1493 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy,
C.sext(SrcBits)));
1495 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy,
C.zext(SrcBits)));
1498 if (
C.isOne() &&
C.getBitWidth() > 1) {
1503 ConstantInt::get(V->getType(), 1));
1515 auto NewPred = (Pred == Cmp.ICMP_EQ) ? Cmp.ICMP_UGE : Cmp.ICMP_ULT;
1517 ConstantInt::get(SrcTy, DstBits - Pow2->
logBase2()));
1523 Pred,
Y, ConstantInt::get(SrcTy,
C.logBase2() - Pow2->
logBase2()));
1529 if (!SrcTy->isVectorTy() && shouldChangeType(DstBits, SrcBits)) {
1533 Constant *WideC = ConstantInt::get(SrcTy,
C.zext(SrcBits));
1542 if ((
Known.Zero |
Known.One).countl_one() >= SrcBits - DstBits) {
1544 APInt NewRHS =
C.zext(SrcBits);
1546 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy, NewRHS));
1558 DstBits == SrcBits - ShAmt) {
1575 bool YIsSExt =
false;
1578 unsigned NoWrapFlags =
cast<TruncInst>(Cmp.getOperand(0))->getNoWrapKind() &
1580 if (Cmp.isSigned()) {
1591 if (
X->getType() !=
Y->getType() &&
1592 (!Cmp.getOperand(0)->hasOneUse() || !Cmp.getOperand(1)->hasOneUse()))
1594 if (!isDesirableIntType(
X->getType()->getScalarSizeInBits()) &&
1595 isDesirableIntType(
Y->getType()->getScalarSizeInBits())) {
1597 Pred = Cmp.getSwappedPredicate(Pred);
1602 else if (!Cmp.isSigned() &&
1616 Type *TruncTy = Cmp.getOperand(0)->getType();
1621 if (isDesirableIntType(TruncBits) &&
1622 !isDesirableIntType(
X->getType()->getScalarSizeInBits()))
1645 bool TrueIfSigned =
false;
1662 if (
Xor->hasOneUse()) {
1664 if (!Cmp.isEquality() && XorC->
isSignMask()) {
1665 Pred = Cmp.getFlippedSignednessPredicate();
1666 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(),
C ^ *XorC));
1671 Pred = Cmp.getFlippedSignednessPredicate();
1672 Pred = Cmp.getSwappedPredicate(Pred);
1673 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(),
C ^ *XorC));
1680 if (*XorC == ~
C && (
C + 1).isPowerOf2())
1683 if (*XorC ==
C && (
C + 1).isPowerOf2())
1688 if (*XorC == -
C &&
C.isPowerOf2())
1690 ConstantInt::get(
X->getType(), ~
C));
1692 if (*XorC ==
C && (-
C).isPowerOf2())
1694 ConstantInt::get(
X->getType(), ~
C));
1716 const APInt *ShiftC;
1721 Type *XType =
X->getType();
1727 return new ICmpInst(Pred,
Add, ConstantInt::get(XType, Bound));
1736 if (!Shift || !Shift->
isShift())
1744 unsigned ShiftOpcode = Shift->
getOpcode();
1745 bool IsShl = ShiftOpcode == Instruction::Shl;
1748 APInt NewAndCst, NewCmpCst;
1749 bool AnyCmpCstBitsShiftedOut;
1750 if (ShiftOpcode == Instruction::Shl) {
1758 NewCmpCst = C1.
lshr(*C3);
1759 NewAndCst = C2.
lshr(*C3);
1760 AnyCmpCstBitsShiftedOut = NewCmpCst.
shl(*C3) != C1;
1761 }
else if (ShiftOpcode == Instruction::LShr) {
1766 NewCmpCst = C1.
shl(*C3);
1767 NewAndCst = C2.
shl(*C3);
1768 AnyCmpCstBitsShiftedOut = NewCmpCst.
lshr(*C3) != C1;
1774 assert(ShiftOpcode == Instruction::AShr &&
"Unknown shift opcode");
1775 NewCmpCst = C1.
shl(*C3);
1776 NewAndCst = C2.
shl(*C3);
1777 AnyCmpCstBitsShiftedOut = NewCmpCst.
ashr(*C3) != C1;
1778 if (NewAndCst.
ashr(*C3) != C2)
1782 if (AnyCmpCstBitsShiftedOut) {
1792 Shift->
getOperand(0), ConstantInt::get(
And->getType(), NewAndCst));
1793 return new ICmpInst(Cmp.getPredicate(), NewAnd,
1794 ConstantInt::get(
And->getType(), NewCmpCst));
1811 return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
1825 return new TruncInst(
And->getOperand(0), Cmp.getType());
1836 ConstantInt::get(
X->getType(), ~*C2));
1841 ConstantInt::get(
X->getType(), -*C2));
1844 if (!
And->hasOneUse())
1847 if (Cmp.isEquality() && C1.
isZero()) {
1865 Constant *NegBOC = ConstantInt::get(
And->getType(), -NewC2);
1867 return new ICmpInst(NewPred,
X, NegBOC);
1885 if (!Cmp.getType()->isVectorTy()) {
1886 Type *WideType = W->getType();
1888 Constant *ZextC1 = ConstantInt::get(WideType, C1.
zext(WideScalarBits));
1889 Constant *ZextC2 = ConstantInt::get(WideType, C2->
zext(WideScalarBits));
1891 return new ICmpInst(Cmp.getPredicate(), NewAnd, ZextC1);
1902 if (!Cmp.isSigned() && C1.
isZero() &&
And->getOperand(0)->hasOneUse() &&
1909 unsigned UsesRemoved = 0;
1910 if (
And->hasOneUse())
1912 if (
Or->hasOneUse())
1919 if (UsesRemoved >= RequireUsesRemoved) {
1923 One,
Or->getName());
1925 return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
1939 if (!Cmp.getParent()->getParent()->hasFnAttribute(
1940 Attribute::NoImplicitFloat) &&
1943 Type *FPType = V->getType()->getScalarType();
1944 if (FPType->isIEEELikeFPTy() && (C1.
isZero() || C1 == *C2)) {
1945 APInt ExponentMask =
1947 if (*C2 == ExponentMask) {
1948 unsigned Mask = C1.
isZero()
1982 Constant *MinSignedC = ConstantInt::get(
1986 return new ICmpInst(NewPred,
X, MinSignedC);
2003 if (!Cmp.isEquality())
2013 if (
C.getBitWidth() > 1 && (
C.isZero() ||
C.isOne()) &&
2017 return new ICmpInst(Pred, MatchedX, Cmp.getOperand(1));
2021 return new TruncInst(MatchedX, Cmp.getType());
2025 if (
And->hasOneUse()) {
2026 Value *Trunc =
Builder.CreateTrunc(MatchedX, Cmp.getType());
2034 if (Cmp.getOperand(1) ==
Y &&
C.isNegatedPowerOf2()) {
2045 X->getType()->isIntOrIntVectorTy(1) && (
C.isZero() ||
C.isOne())) {
2051 return BinaryOperator::CreateAnd(TruncY,
X);
2069 const APInt *Addend, *Msk;
2073 APInt NewComperand = (
C - *Addend) & *Msk;
2074 Value *MaskA =
Builder.CreateAnd(
A, ConstantInt::get(
A->getType(), *Msk));
2076 ConstantInt::get(MaskA->
getType(), NewComperand));
2098 while (!WorkList.
empty()) {
2099 auto MatchOrOperatorArgument = [&](
Value *OrOperatorArgument) {
2102 if (
match(OrOperatorArgument,
2108 if (
match(OrOperatorArgument,
2118 Value *OrOperatorLhs, *OrOperatorRhs;
2120 if (!
match(CurrentValue,
2125 MatchOrOperatorArgument(OrOperatorRhs);
2126 MatchOrOperatorArgument(OrOperatorLhs);
2131 Value *LhsCmp = Builder.CreateICmp(Pred, CmpValues.
rbegin()->first,
2132 CmpValues.
rbegin()->second);
2134 for (
auto It = CmpValues.
rbegin() + 1; It != CmpValues.
rend(); ++It) {
2135 Value *RhsCmp = Builder.CreateICmp(Pred, It->first, It->second);
2136 LhsCmp = Builder.CreateBinOp(BOpc, LhsCmp, RhsCmp);
2152 ConstantInt::get(V->getType(), 1));
2155 Value *OrOp0 =
Or->getOperand(0), *OrOp1 =
Or->getOperand(1);
2162 Builder.CreateXor(OrOp1, ConstantInt::get(OrOp1->getType(),
C));
2163 return new ICmpInst(Pred, OrOp0, NewC);
2167 if (
match(OrOp1,
m_APInt(MaskC)) && Cmp.isEquality()) {
2168 if (*MaskC ==
C && (
C + 1).isPowerOf2()) {
2173 return new ICmpInst(Pred, OrOp0, OrOp1);
2180 if (
Or->hasOneUse()) {
2182 Constant *NewC = ConstantInt::get(
Or->getType(),
C ^ (*MaskC));
2194 Constant *NewC = ConstantInt::get(
X->getType(), TrueIfSigned ? 1 : 0);
2222 if (!Cmp.isEquality() || !
C.isZero() || !
Or->hasOneUse())
2253 if (
X ==
Mul->getOperand(1) && !Cmp.isSigned()) {
2255 bool IsSqr =
C == R * R;
2258 if (Cmp.isEquality() &&
2259 (
Mul->hasNoUnsignedWrap() || (
Mul->hasNoSignedWrap() &&
C.isZero()))) {
2267 return new ICmpInst(Pred,
X, ConstantInt::get(MulTy, R));
2272 if (
Mul->hasNoUnsignedWrap()) {
2275 return new ICmpInst(Pred,
X, ConstantInt::get(MulTy, R));
2289 return new ICmpInst(Cmp.getStrictPredicate(),
X,
2290 ConstantInt::get(MulTy, R));
2313 if (Cmp.isEquality()) {
2315 if (
Mul->hasNoSignedWrap() &&
C.srem(*MulC).isZero()) {
2316 Constant *NewC = ConstantInt::get(MulTy,
C.sdiv(*MulC));
2324 if (
C.urem(*MulC).isZero()) {
2327 if ((*MulC & 1).isOne() ||
Mul->hasNoUnsignedWrap()) {
2328 Constant *NewC = ConstantInt::get(MulTy,
C.udiv(*MulC));
2341 if (
C.isMinSignedValue() && MulC->
isAllOnes())
2347 NewC = ConstantInt::get(
2351 "Unexpected predicate");
2352 NewC = ConstantInt::get(
2357 NewC = ConstantInt::get(
2361 "Unexpected predicate");
2362 NewC = ConstantInt::get(
2367 return NewC ?
new ICmpInst(Pred,
X, NewC) :
nullptr;
2379 unsigned TypeBits =
C.getBitWidth();
2381 if (Cmp.isUnsigned()) {
2401 return new ICmpInst(Pred,
Y, ConstantInt::get(ShiftType, CLog2));
2402 }
else if (Cmp.isSigned() && C2->
isOne()) {
2403 Constant *BitWidthMinusOne = ConstantInt::get(ShiftType, TypeBits - 1);
2424 const APInt *ShiftVal;
2454 const APInt *ShiftAmt;
2460 unsigned TypeBits =
C.getBitWidth();
2461 if (ShiftAmt->
uge(TypeBits))
2473 APInt ShiftedC =
C.ashr(*ShiftAmt);
2474 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2477 C.ashr(*ShiftAmt).shl(*ShiftAmt) ==
C) {
2478 APInt ShiftedC =
C.ashr(*ShiftAmt);
2479 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2486 assert(!
C.isMinSignedValue() &&
"Unexpected icmp slt");
2487 APInt ShiftedC = (
C - 1).ashr(*ShiftAmt) + 1;
2488 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2498 APInt ShiftedC =
C.lshr(*ShiftAmt);
2499 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2502 C.lshr(*ShiftAmt).shl(*ShiftAmt) ==
C) {
2503 APInt ShiftedC =
C.lshr(*ShiftAmt);
2504 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2511 assert(
C.ugt(0) &&
"ult 0 should have been eliminated");
2512 APInt ShiftedC = (
C - 1).lshr(*ShiftAmt) + 1;
2513 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2517 if (Cmp.isEquality() && Shl->
hasOneUse()) {
2523 Constant *LShrC = ConstantInt::get(ShType,
C.lshr(*ShiftAmt));
2528 bool TrueIfSigned =
false;
2540 if (Cmp.isUnsigned() && Shl->
hasOneUse()) {
2542 if ((
C + 1).isPowerOf2() &&
2550 if (
C.isPowerOf2() &&
2580 Pred, ConstantInt::get(ShType->
getContext(),
C))) {
2581 CmpPred = FlippedStrictness->first;
2589 ConstantInt::get(TruncTy, RHSC.
ashr(*ShiftAmt).
trunc(TypeBits - Amt));
2591 Builder.CreateTrunc(
X, TruncTy,
"",
false,
2608 if (Cmp.isEquality() && Shr->
isExact() &&
C.isZero())
2609 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
2611 bool IsAShr = Shr->
getOpcode() == Instruction::AShr;
2612 const APInt *ShiftValC;
2614 if (Cmp.isEquality())
2632 assert(ShiftValC->
uge(
C) &&
"Expected simplify of compare");
2633 assert((IsUGT || !
C.isZero()) &&
"Expected X u< 0 to simplify");
2635 unsigned CmpLZ = IsUGT ?
C.countl_zero() : (
C - 1).
countl_zero();
2643 const APInt *ShiftAmtC;
2649 unsigned TypeBits =
C.getBitWidth();
2651 if (ShAmtVal >= TypeBits || ShAmtVal == 0)
2654 bool IsExact = Shr->
isExact();
2662 (
C - 1).isPowerOf2() &&
C.countLeadingZeros() > ShAmtVal) {
2668 APInt ShiftedC = (
C - 1).shl(ShAmtVal) + 1;
2669 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2675 APInt ShiftedC =
C.shl(ShAmtVal);
2676 if (ShiftedC.
ashr(ShAmtVal) ==
C)
2677 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2681 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2682 if (!
C.isMaxSignedValue() && !(
C + 1).shl(ShAmtVal).isMinSignedValue() &&
2683 (ShiftedC + 1).ashr(ShAmtVal) == (
C + 1))
2684 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2690 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2691 if ((ShiftedC + 1).ashr(ShAmtVal) == (
C + 1) ||
2692 (
C + 1).shl(ShAmtVal).isMinSignedValue())
2693 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2700 if (
C.getBitWidth() > 2 &&
C.getNumSignBits() <= ShAmtVal) {
2710 }
else if (!IsAShr) {
2714 APInt ShiftedC =
C.shl(ShAmtVal);
2715 if (ShiftedC.
lshr(ShAmtVal) ==
C)
2716 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2720 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2721 if ((ShiftedC + 1).lshr(ShAmtVal) == (
C + 1))
2722 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2726 if (!Cmp.isEquality())
2734 assert(((IsAShr &&
C.shl(ShAmtVal).ashr(ShAmtVal) ==
C) ||
2735 (!IsAShr &&
C.shl(ShAmtVal).lshr(ShAmtVal) ==
C)) &&
2736 "Expected icmp+shr simplify did not occur.");
2741 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy,
C << ShAmtVal));
2747 Constant *Mask = ConstantInt::get(ShrTy, Val);
2749 return new ICmpInst(Pred,
And, ConstantInt::get(ShrTy,
C << ShAmtVal));
2766 const APInt *DivisorC;
2775 "ult X, 0 should have been simplified already.");
2780 if (!NormalizedC.
uge(DivisorC->
abs() - 1))
2803 const APInt *DivisorC;
2812 !
C.isStrictlyPositive()))
2818 Constant *MaskC = ConstantInt::get(Ty, SignMask | (*DivisorC - 1));
2822 return new ICmpInst(Pred,
And, ConstantInt::get(Ty,
C));
2849 assert(*C2 != 0 &&
"udiv 0, X should have been simplified already.");
2854 "icmp ugt X, UINT_MAX should have been simplified already.");
2856 ConstantInt::get(Ty, C2->
udiv(
C + 1)));
2861 assert(
C != 0 &&
"icmp ult X, 0 should have been simplified already.");
2863 ConstantInt::get(Ty, C2->
udiv(
C)));
2877 bool DivIsSigned = Div->
getOpcode() == Instruction::SDiv;
2887 if (Cmp.isEquality() && Div->
hasOneUse() &&
C.isSignBitSet() &&
2888 (!DivIsSigned ||
C.isMinSignedValue())) {
2889 Value *XBig =
Builder.CreateICmp(Pred,
X, ConstantInt::get(Ty,
C));
2890 Value *YOne =
Builder.CreateICmp(Pred,
Y, ConstantInt::get(Ty, 1));
2916 if (!Cmp.isEquality() && DivIsSigned != Cmp.isSigned()) {
2920 DivIsSigned =
false;
2939 bool ProdOV = (DivIsSigned ? Prod.
sdiv(*C2) : Prod.
udiv(*C2)) !=
C;
2952 int LoOverflow = 0, HiOverflow = 0;
2953 APInt LoBound, HiBound;
2958 HiOverflow = LoOverflow = ProdOV;
2967 LoBound = -(RangeSize - 1);
2968 HiBound = RangeSize;
2969 }
else if (
C.isStrictlyPositive()) {
2971 HiOverflow = LoOverflow = ProdOV;
2977 LoOverflow = HiOverflow = ProdOV ? -1 : 0;
2979 APInt DivNeg = -RangeSize;
2980 LoOverflow =
addWithOverflow(LoBound, HiBound, DivNeg,
true) ? -1 : 0;
2988 LoBound = RangeSize + 1;
2989 HiBound = -RangeSize;
2990 if (HiBound == *C2) {
2994 }
else if (
C.isStrictlyPositive()) {
2997 HiOverflow = LoOverflow = ProdOV ? -1 : 0;
3003 LoOverflow = HiOverflow = ProdOV;
3016 if (LoOverflow && HiOverflow)
3020 X, ConstantInt::get(Ty, LoBound));
3023 X, ConstantInt::get(Ty, HiBound));
3027 if (LoOverflow && HiOverflow)
3031 X, ConstantInt::get(Ty, LoBound));
3034 X, ConstantInt::get(Ty, HiBound));
3039 if (LoOverflow == +1)
3041 if (LoOverflow == -1)
3043 return new ICmpInst(Pred,
X, ConstantInt::get(Ty, LoBound));
3046 if (HiOverflow == +1)
3048 if (HiOverflow == -1)
3090 bool HasNSW =
Sub->hasNoSignedWrap();
3091 bool HasNUW =
Sub->hasNoUnsignedWrap();
3093 ((Cmp.isUnsigned() && HasNUW) || (Cmp.isSigned() && HasNSW)) &&
3095 return new ICmpInst(SwappedPred,
Y, ConstantInt::get(Ty, SubResult));
3103 if (Cmp.isEquality() &&
C.isZero() &&
3104 none_of((
Sub->users()), [](
const User *U) { return isa<PHINode>(U); }))
3112 if (!
Sub->hasOneUse())
3115 if (
Sub->hasNoSignedWrap()) {
3139 (*C2 & (
C - 1)) == (
C - 1))
3152 return new ICmpInst(SwappedPred,
Add, ConstantInt::get(Ty, ~
C));
3158 auto FoldConstant = [&](
bool Val) {
3159 Constant *Res = Val ? Builder.getTrue() : Builder.getFalse();
3166 switch (
Table.to_ulong()) {
3168 return FoldConstant(
false);
3170 return HasOneUse ? Builder.CreateNot(Builder.CreateOr(Op0, Op1)) :
nullptr;
3172 return HasOneUse ? Builder.CreateAnd(Builder.CreateNot(Op0), Op1) :
nullptr;
3174 return Builder.CreateNot(Op0);
3176 return HasOneUse ? Builder.CreateAnd(Op0, Builder.CreateNot(Op1)) :
nullptr;
3178 return Builder.CreateNot(Op1);
3180 return Builder.CreateXor(Op0, Op1);
3182 return HasOneUse ? Builder.CreateNot(Builder.CreateAnd(Op0, Op1)) :
nullptr;
3184 return Builder.CreateAnd(Op0, Op1);
3186 return HasOneUse ? Builder.CreateNot(Builder.CreateXor(Op0, Op1)) :
nullptr;
3190 return HasOneUse ? Builder.CreateOr(Builder.CreateNot(Op0), Op1) :
nullptr;
3194 return HasOneUse ? Builder.CreateOr(Op0, Builder.CreateNot(Op1)) :
nullptr;
3196 return Builder.CreateOr(Op0, Op1);
3198 return FoldConstant(
true);
3213 Cmp.getType() !=
A->getType() || Cmp.getType() !=
B->getType())
3216 std::bitset<4>
Table;
3217 auto ComputeTable = [&](
bool First,
bool Second) -> std::optional<bool> {
3221 auto *Val = Res->getType()->isVectorTy() ? Res->getSplatValue() : Res;
3225 return std::nullopt;
3228 for (
unsigned I = 0;
I < 4; ++
I) {
3229 bool First = (
I >> 1) & 1;
3230 bool Second =
I & 1;
3231 if (
auto Res = ComputeTable(
First, Second))
3253 const APInt *ShAmtC;
3261 return new ICmpInst(Pred,
A, ConstantInt::get(
A->getType(),
C));
3273 if (
Add->hasNoUnsignedWrap() &&
3276 APInt NewC =
C.usub_ov(*C2, Overflow);
3280 return new ICmpInst(Pred,
X, ConstantInt::get(Ty, NewC));
3285 if (
Add->hasNoSignedWrap() &&
3288 APInt NewC =
C.ssub_ov(*C2, Overflow);
3292 return new ICmpInst(ChosenPred,
X, ConstantInt::get(Ty, NewC));
3296 C.isNonNegative() && (
C - *C2).isNonNegative() &&
3299 .isAllNonNegative())
3301 ConstantInt::get(Ty,
C - *C2));
3306 if (Cmp.isSigned()) {
3307 if (
Lower.isSignMask())
3309 if (
Upper.isSignMask())
3312 if (
Lower.isMinValue())
3314 if (
Upper.isMinValue())
3347 if (!
Add->hasOneUse())
3362 ConstantInt::get(Ty,
C * 2));
3376 Builder.CreateAdd(
X, ConstantInt::get(Ty, *C2 -
C - 1)),
3377 ConstantInt::get(Ty, ~
C));
3382 Type *NewCmpTy = V->getType();
3384 if (shouldChangeType(Ty, NewCmpTy)) {
3395 :
Builder.CreateAdd(V, ConstantInt::get(NewCmpTy, EquivOffset)),
3396 ConstantInt::get(NewCmpTy, EquivInt));
3418 Value *EqualVal =
SI->getTrueValue();
3419 Value *UnequalVal =
SI->getFalseValue();
3442 auto FlippedStrictness =
3444 if (!FlippedStrictness)
3447 "basic correctness failure");
3448 RHS2 = FlippedStrictness->second;
3460 assert(
C &&
"Cmp RHS should be a constant int!");
3466 Value *OrigLHS, *OrigRHS;
3467 ConstantInt *C1LessThan, *C2Equal, *C3GreaterThan;
3468 if (Cmp.hasOneUse() &&
3471 assert(C1LessThan && C2Equal && C3GreaterThan);
3474 C1LessThan->
getValue(),
C->getValue(), Cmp.getPredicate());
3476 Cmp.getPredicate());
3478 C3GreaterThan->
getValue(),
C->getValue(), Cmp.getPredicate());
3489 if (TrueWhenLessThan)
3495 if (TrueWhenGreaterThan)
3510 Value *Op1 = Cmp.getOperand(1);
3511 Value *BCSrcOp = Bitcast->getOperand(0);
3512 Type *SrcType = Bitcast->getSrcTy();
3513 Type *DstType = Bitcast->getType();
3517 if (SrcType->isVectorTy() == DstType->isVectorTy() &&
3518 SrcType->getScalarSizeInBits() == DstType->getScalarSizeInBits()) {
3533 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(), 1));
3560 Type *XType =
X->getType();
3563 if (!(XType->
isPPC_FP128Ty() || SrcType->isPPC_FP128Ty())) {
3578 Type *FPType = SrcType->getScalarType();
3579 if (!Cmp.getParent()->getParent()->hasFnAttribute(
3580 Attribute::NoImplicitFloat) &&
3581 Cmp.isEquality() && FPType->isIEEELikeFPTy()) {
3587 Builder.createIsFPClass(BCSrcOp, Mask));
3610 if (!
match(Cmp.getOperand(1),
m_APInt(
C)) || !DstType->isIntegerTy() ||
3611 !SrcType->isIntOrIntVectorTy())
3621 if (Cmp.isEquality() &&
C->isAllOnes() && Bitcast->hasOneUse()) {
3622 if (
Value *NotBCSrcOp =
3624 Value *Cast =
Builder.CreateBitCast(NotBCSrcOp, DstType);
3633 if (Cmp.isEquality() &&
C->isZero() && Bitcast->hasOneUse() &&
3636 Type *NewType =
Builder.getIntNTy(VecTy->getPrimitiveSizeInBits());
3656 if (
C->isSplat(EltTy->getBitWidth())) {
3662 Value *Extract =
Builder.CreateExtractElement(Vec, Mask[0]);
3663 Value *NewC = ConstantInt::get(EltTy,
C->trunc(EltTy->getBitWidth()));
3664 return new ICmpInst(Pred, Extract, NewC);
3702 if (
match(Cmp.getOperand(0),
3708 bool ValidPred =
true;
3726 X->getType()->getScalarType()->getFltSemantics();
3729 if (!Exp.isNegative() && Exp.sle(MaxExp + 1) &&
3731 int ExpVal =
static_cast<int>(Exp.getSExtValue());
3736 ConstantFP::get(
X->getType(), CmpConst));
3745 Value *Cmp0 = Cmp.getOperand(0);
3747 if (
C->isZero() && Cmp.isEquality() && Cmp0->
hasOneUse() &&
3754 return new ICmpInst(Cmp.getPredicate(),
X,
Y);
3769 if (!Cmp.isEquality())
3778 case Instruction::SRem:
3789 case Instruction::Add: {
3796 }
else if (
C.isZero()) {
3799 if (
Value *NegVal = dyn_castNegVal(BOp1))
3800 return new ICmpInst(Pred, BOp0, NegVal);
3801 if (
Value *NegVal = dyn_castNegVal(BOp0))
3802 return new ICmpInst(Pred, NegVal, BOp1);
3811 return new ICmpInst(Pred, BOp0, Neg);
3816 case Instruction::Xor:
3821 }
else if (
C.isZero()) {
3823 return new ICmpInst(Pred, BOp0, BOp1);
3826 case Instruction::Or: {
3847 Cond->getType() == Cmp.getType()) {
3885 case Instruction::UDiv:
3886 case Instruction::SDiv:
3896 return new ICmpInst(Pred, BOp0, BOp1);
3899 Instruction::Mul, BO->
getOpcode() == Instruction::SDiv, BOp1,
3900 Cmp.getOperand(1), BO);
3904 return new ICmpInst(Pred, YC, BOp0);
3908 if (BO->
getOpcode() == Instruction::UDiv &&
C.isZero()) {
3911 return new ICmpInst(NewPred, BOp1, BOp0);
3925 "Non-ctpop intrin in ctpop fold");
3960 Type *Ty =
II->getType();
3964 switch (
II->getIntrinsicID()) {
3965 case Intrinsic::abs:
3968 if (
C.isZero() ||
C.isMinSignedValue())
3969 return new ICmpInst(Pred,
II->getArgOperand(0), ConstantInt::get(Ty,
C));
3972 case Intrinsic::bswap:
3974 return new ICmpInst(Pred,
II->getArgOperand(0),
3975 ConstantInt::get(Ty,
C.byteSwap()));
3977 case Intrinsic::bitreverse:
3979 return new ICmpInst(Pred,
II->getArgOperand(0),
3980 ConstantInt::get(Ty,
C.reverseBits()));
3982 case Intrinsic::ctlz:
3983 case Intrinsic::cttz: {
3986 return new ICmpInst(Pred,
II->getArgOperand(0),
3992 unsigned Num =
C.getLimitedValue(
BitWidth);
3994 bool IsTrailing =
II->getIntrinsicID() == Intrinsic::cttz;
3997 APInt Mask2 = IsTrailing
4001 ConstantInt::get(Ty, Mask2));
4006 case Intrinsic::ctpop: {
4009 bool IsZero =
C.isZero();
4011 return new ICmpInst(Pred,
II->getArgOperand(0),
4018 case Intrinsic::fshl:
4019 case Intrinsic::fshr:
4020 if (
II->getArgOperand(0) ==
II->getArgOperand(1)) {
4021 const APInt *RotAmtC;
4025 return new ICmpInst(Pred,
II->getArgOperand(0),
4026 II->getIntrinsicID() == Intrinsic::fshl
4027 ? ConstantInt::get(Ty,
C.rotr(*RotAmtC))
4028 : ConstantInt::get(Ty,
C.rotl(*RotAmtC)));
4032 case Intrinsic::umax:
4033 case Intrinsic::uadd_sat: {
4036 if (
C.isZero() &&
II->hasOneUse()) {
4043 case Intrinsic::ssub_sat:
4048 if (
C.isZero() &&
II->getType()->getScalarSizeInBits() > 1)
4049 return new ICmpInst(Pred,
II->getArgOperand(0),
II->getArgOperand(1));
4051 case Intrinsic::usub_sat: {
4056 return new ICmpInst(NewPred,
II->getArgOperand(0),
II->getArgOperand(1));
4071 assert(Cmp.isEquality());
4074 Value *Op0 = Cmp.getOperand(0);
4075 Value *Op1 = Cmp.getOperand(1);
4078 if (!IIOp0 || !IIOp1 || IIOp0->getIntrinsicID() != IIOp1->getIntrinsicID())
4081 switch (IIOp0->getIntrinsicID()) {
4082 case Intrinsic::bswap:
4083 case Intrinsic::bitreverse:
4086 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
4087 case Intrinsic::fshl:
4088 case Intrinsic::fshr: {
4091 if (IIOp0->getOperand(0) != IIOp0->getOperand(1))
4093 if (IIOp1->getOperand(0) != IIOp1->getOperand(1))
4095 if (IIOp0->getOperand(2) == IIOp1->getOperand(2))
4096 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
4102 const unsigned BW = IIOp0->getType()->getScalarSizeInBits();
4103 unsigned OneUses = IIOp0->hasOneUse() + IIOp1->hasOneUse();
4112 Builder.CreateSub(IIOp0->getOperand(2), IIOp1->getOperand(2));
4113 Value *CombinedRotate = Builder.CreateIntrinsic(
4114 Op0->
getType(), IIOp0->getIntrinsicID(),
4115 {IIOp0->getOperand(0), IIOp0->getOperand(0), SubAmt});
4116 return new ICmpInst(Pred, IIOp1->getOperand(0), CombinedRotate);
4135 switch (
II->getIntrinsicID()) {
4138 case Intrinsic::fshl:
4139 case Intrinsic::fshr:
4140 if (Cmp.isEquality() &&
II->getArgOperand(0) ==
II->getArgOperand(1)) {
4142 if (
C.isZero() ||
C.isAllOnes())
4143 return new ICmpInst(Pred,
II->getArgOperand(0), Cmp.getOperand(1));
4157 case Instruction::Xor:
4161 case Instruction::And:
4165 case Instruction::Or:
4169 case Instruction::Mul:
4173 case Instruction::Shl:
4177 case Instruction::LShr:
4178 case Instruction::AShr:
4182 case Instruction::SRem:
4186 case Instruction::UDiv:
4190 case Instruction::SDiv:
4194 case Instruction::Sub:
4198 case Instruction::Add:
4222 if (!
II->hasOneUse())
4238 Value *Op0 =
II->getOperand(0);
4239 Value *Op1 =
II->getOperand(1);
4248 switch (
II->getIntrinsicID()) {
4251 "This function only works with usub_sat and uadd_sat for now!");
4252 case Intrinsic::uadd_sat:
4255 case Intrinsic::usub_sat:
4265 II->getBinaryOp(), *COp1,
II->getNoWrapKind());
4272 if (
II->getBinaryOp() == Instruction::Add)
4278 SatValCheck ? Instruction::BinaryOps::Or : Instruction::BinaryOps::And;
4280 std::optional<ConstantRange> Combination;
4281 if (CombiningOp == Instruction::BinaryOps::Or)
4293 Combination->getEquivalentICmp(EquivPred, EquivInt, EquivOffset);
4297 Builder.CreateAdd(Op0, ConstantInt::get(Op1->
getType(), EquivOffset)),
4298 ConstantInt::get(Op1->
getType(), EquivInt));
4305 std::optional<ICmpInst::Predicate> NewPredicate = std::nullopt;
4310 NewPredicate = Pred;
4314 else if (
C.isAllOnes())
4322 else if (
C.isZero())
4339 if (!
C.isZero() && !
C.isAllOnes())
4350 if (
I->getIntrinsicID() == Intrinsic::scmp)
4364 switch (
II->getIntrinsicID()) {
4367 case Intrinsic::uadd_sat:
4368 case Intrinsic::usub_sat:
4373 case Intrinsic::ctpop: {
4378 case Intrinsic::scmp:
4379 case Intrinsic::ucmp:
4385 if (Cmp.isEquality())
4388 Type *Ty =
II->getType();
4390 switch (
II->getIntrinsicID()) {
4391 case Intrinsic::ctpop: {
4403 case Intrinsic::ctlz: {
4406 unsigned Num =
C.getLimitedValue();
4409 II->getArgOperand(0), ConstantInt::get(Ty, Limit));
4414 unsigned Num =
C.getLimitedValue();
4417 II->getArgOperand(0), ConstantInt::get(Ty, Limit));
4421 case Intrinsic::cttz: {
4423 if (!
II->hasOneUse())
4430 Builder.CreateAnd(
II->getArgOperand(0), Mask),
4438 Builder.CreateAnd(
II->getArgOperand(0), Mask),
4443 case Intrinsic::ssub_sat:
4450 return new ICmpInst(Pred,
II->getArgOperand(0),
II->getArgOperand(1));
4454 II->getArgOperand(1));
4458 II->getArgOperand(1));
4461 case Intrinsic::abs: {
4462 if (!
II->hasOneUse())
4471 Builder.CreateAdd(
X, ConstantInt::get(Ty,
C)),
4472 ConstantInt::get(Ty, 2 *
C));
4479 Builder.CreateAdd(
X, ConstantInt::get(Ty,
C - 1)),
4480 ConstantInt::get(Ty, 2 * (
C - 1)));
4493 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
4500 case Instruction::IntToPtr:
4505 APInt NullPtrValue =
4513 case Instruction::Load:
4530 auto SimplifyOp = [&](
Value *
Op,
bool SelectCondIsTrue) ->
Value * {
4534 SI->getCondition(), Pred,
Op, RHS,
DL, SelectCondIsTrue))
4535 return ConstantInt::get(
I.getType(), *Impl);
4540 Value *Op1 = SimplifyOp(
SI->getOperand(1),
true);
4544 Value *Op2 = SimplifyOp(
SI->getOperand(2),
false);
4548 auto Simplifies = [&](
Value *
Op,
unsigned Idx) {
4563 bool Transform =
false;
4566 else if (Simplifies(Op1, 1) || Simplifies(Op2, 2)) {
4568 if (
SI->hasOneUse())
4571 else if (CI && !CI->
isZero())
4579 Op1 =
Builder.CreateICmp(Pred,
SI->getOperand(1), RHS,
I.getName());
4581 Op2 =
Builder.CreateICmp(Pred,
SI->getOperand(2), RHS,
I.getName());
4592 const APInt *C1, *C2, *
P;
4599 if (C1SatisfiesCond && !C2SatisfiesCond) {
4603 Value *Cmp2 =
Builder.CreateICmp(Pred, RHS,
SI->getFalseValue());
4605 return BinaryOperator::CreateOr(Cmp1, Cmp2);
4606 return BinaryOperator::CreateAnd(Cmp1, Cmp2);
4616 unsigned Depth = 0) {
4619 if (V->getType()->getScalarSizeInBits() == 1)
4627 switch (
I->getOpcode()) {
4628 case Instruction::ZExt:
4631 case Instruction::SExt:
4635 case Instruction::And:
4636 case Instruction::Or:
4643 case Instruction::Xor:
4653 case Instruction::Select:
4657 case Instruction::Shl:
4660 case Instruction::LShr:
4663 case Instruction::AShr:
4667 case Instruction::Add:
4673 case Instruction::Sub:
4679 case Instruction::Call: {
4681 switch (
II->getIntrinsicID()) {
4684 case Intrinsic::umax:
4685 case Intrinsic::smax:
4686 case Intrinsic::umin:
4687 case Intrinsic::smin:
4692 case Intrinsic::bitreverse:
4782 auto IsLowBitMask = [&]() {
4800 auto Check = [&]() {
4818 auto Check = [&]() {
4837 if (!IsLowBitMask())
4856 const APInt *C0, *C1;
4873 const APInt &MaskedBits = *C0;
4874 assert(MaskedBits != 0 &&
"shift by zero should be folded away already.");
4895 auto *XType =
X->getType();
4896 const unsigned XBitWidth = XType->getScalarSizeInBits();
4898 assert(
BitWidth.ugt(MaskedBits) &&
"shifts should leave some bits untouched");
4911 Value *T0 = Builder.CreateAdd(
X, ConstantInt::get(XType, AddCst));
4913 Value *
T1 = Builder.CreateICmp(DstPred, T0, ConstantInt::get(XType, ICmpCst));
4929 !
I.getOperand(0)->hasOneUse())
4954 assert(NarrowestTy ==
I.getOperand(0)->getType() &&
4955 "We did not look past any shifts while matching XShift though.");
4956 bool HadTrunc = WidestTy !=
I.getOperand(0)->getType();
4963 auto XShiftOpcode = XShift->
getOpcode();
4964 if (XShiftOpcode == YShift->
getOpcode())
4967 Value *
X, *XShAmt, *
Y, *YShAmt;
4976 if (!
match(
I.getOperand(0),
5002 unsigned MaximalPossibleTotalShiftAmount =
5005 APInt MaximalRepresentableShiftAmount =
5007 if (MaximalRepresentableShiftAmount.
ult(MaximalPossibleTotalShiftAmount))
5016 if (NewShAmt->getType() != WidestTy) {
5026 if (!
match(NewShAmt,
5028 APInt(WidestBitWidth, WidestBitWidth))))
5033 auto CanFold = [NewShAmt, WidestBitWidth, NarrowestShift, SQ,
5039 ? NewShAmt->getSplatValue()
5042 if (NewShAmtSplat &&
5050 unsigned MinLeadZero =
Known.countMinLeadingZeros();
5052 unsigned MaxActiveBits =
Known.getBitWidth() - MinLeadZero;
5053 if (MaxActiveBits <= 1)
5061 unsigned MinLeadZero =
Known.countMinLeadingZeros();
5063 unsigned MaxActiveBits =
Known.getBitWidth() - MinLeadZero;
5064 if (MaxActiveBits <= 1)
5067 if (NewShAmtSplat) {
5070 if (AdjNewShAmt.
ule(MinLeadZero))
5081 X = Builder.CreateZExt(
X, WidestTy);
5082 Y = Builder.CreateZExt(
Y, WidestTy);
5084 Value *T0 = XShiftOpcode == Instruction::BinaryOps::LShr
5085 ? Builder.CreateLShr(
X, NewShAmt)
5086 : Builder.CreateShl(
X, NewShAmt);
5087 Value *
T1 = Builder.CreateAnd(T0,
Y);
5088 return Builder.CreateICmp(
I.getPredicate(),
T1,
5106 if (!
I.isEquality() &&
5116 NeedNegation =
false;
5119 NeedNegation =
true;
5125 if (
I.isEquality() &&
5140 bool MulHadOtherUses =
Mul && !
Mul->hasOneUse();
5141 if (MulHadOtherUses)
5145 Div->
getOpcode() == Instruction::UDiv ? Intrinsic::umul_with_overflow
5146 : Intrinsic::smul_with_overflow,
5147 X->getType(), {X, Y},
nullptr,
"mul");
5152 if (MulHadOtherUses)
5157 Res =
Builder.CreateNot(Res,
"mul.not.ov");
5161 if (MulHadOtherUses)
5187 Type *Ty =
X->getType();
5191 Value *
And = Builder.CreateAnd(
X, MaxSignedVal);
5201 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5263 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5298 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5314 return new ICmpInst(PredOut, Op0, Op1);
5334 return new ICmpInst(NewPred, Op0, Const);
5346 if (!
C.isPowerOf2())
5359 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5374 Value *Dividend, *Divisor;
5375 if (
I.isEquality() &&
5380 return new ICmpInst(NewPred, Dividend, Divisor);
5439 return new ICmpInst(NewPred, Op1, Zero);
5448 return new ICmpInst(NewPred, Op0, Zero);
5452 bool NoOp0WrapProblem =
false, NoOp1WrapProblem =
false;
5453 bool Op0HasNUW =
false, Op1HasNUW =
false;
5454 bool Op0HasNSW =
false, Op1HasNSW =
false;
5458 bool &HasNSW,
bool &HasNUW) ->
bool {
5465 }
else if (BO.
getOpcode() == Instruction::Or) {
5475 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr;
5479 NoOp0WrapProblem = hasNoWrapProblem(*BO0, Pred, Op0HasNSW, Op0HasNUW);
5483 NoOp1WrapProblem = hasNoWrapProblem(*BO1, Pred, Op1HasNSW, Op1HasNUW);
5488 if ((
A == Op1 ||
B == Op1) && NoOp0WrapProblem)
5494 if ((
C == Op0 ||
D == Op0) && NoOp1WrapProblem)
5499 if (
A &&
C && (
A ==
C ||
A ==
D ||
B ==
C ||
B ==
D) && NoOp0WrapProblem &&
5507 }
else if (
A ==
D) {
5511 }
else if (
B ==
C) {
5528 bool IsNegative) ->
bool {
5529 const APInt *OffsetC;
5541 if (!
C.isStrictlyPositive())
5568 if (
A && NoOp0WrapProblem && IsAddOrSignedPred &&
5569 ShareCommonDivisor(
A, Op1,
B, IsNegative))
5579 if (
C && NoOp1WrapProblem &&
5580 ShareCommonDivisor(Op0,
C,
D,
5593 if (
A &&
C && NoOp0WrapProblem && NoOp1WrapProblem &&
5595 const APInt *AP1, *AP2;
5603 if (AP1Abs.
uge(AP2Abs)) {
5604 APInt Diff = *AP1 - *AP2;
5607 A, C3,
"", Op0HasNUW && Diff.
ule(*AP1), Op0HasNSW);
5610 APInt Diff = *AP2 - *AP1;
5613 C, C3,
"", Op1HasNUW && Diff.
ule(*AP2), Op1HasNSW);
5632 if (BO0 && BO0->
getOpcode() == Instruction::Sub) {
5636 if (BO1 && BO1->
getOpcode() == Instruction::Sub) {
5642 if (
A == Op1 && NoOp0WrapProblem)
5645 if (
C == Op0 && NoOp1WrapProblem)
5665 if (
B &&
D &&
B ==
D && NoOp0WrapProblem && NoOp1WrapProblem)
5669 if (
A &&
C &&
A ==
C && NoOp0WrapProblem && NoOp1WrapProblem)
5677 if (RHSC->isNotMinSignedValue())
5678 return new ICmpInst(
I.getSwappedPredicate(),
X,
5696 if (Op0HasNSW && Op1HasNSW) {
5703 SQ.getWithInstruction(&
I));
5708 SQ.getWithInstruction(&
I));
5709 if (GreaterThan &&
match(GreaterThan,
m_One()))
5716 if (((Op0HasNSW && Op1HasNSW) || (Op0HasNUW && Op1HasNUW)) &&
5728 if (NonZero && BO0 && BO1 && Op0HasNSW && Op1HasNSW)
5735 if (NonZero && BO0 && BO1 && Op0HasNUW && Op1HasNUW)
5746 else if (BO1 && BO1->
getOpcode() == Instruction::SRem &&
5776 case Instruction::Add:
5777 case Instruction::Sub:
5778 case Instruction::Xor: {
5785 if (
C->isSignMask()) {
5791 if (BO0->
getOpcode() == Instruction::Xor &&
C->isMaxSignedValue()) {
5793 NewPred =
I.getSwappedPredicate(NewPred);
5799 case Instruction::Mul: {
5800 if (!
I.isEquality())
5808 if (
unsigned TZs =
C->countr_zero()) {
5814 return new ICmpInst(Pred, And1, And2);
5819 case Instruction::UDiv:
5820 case Instruction::LShr:
5825 case Instruction::SDiv:
5831 case Instruction::AShr:
5836 case Instruction::Shl: {
5837 bool NUW = Op0HasNUW && Op1HasNUW;
5838 bool NSW = Op0HasNSW && Op1HasNSW;
5841 if (!NSW &&
I.isSigned())
5905 auto IsCondKnownTrue = [](
Value *Val) -> std::optional<bool> {
5907 return std::nullopt;
5912 return std::nullopt;
5918 Pred = Pred.dropSameSign();
5921 if (!CmpXZ.has_value() && !CmpYZ.has_value())
5923 if (!CmpXZ.has_value()) {
5929 if (CmpYZ.has_value())
5953 if (!MinMaxCmpXZ.has_value()) {
5961 if (!MinMaxCmpXZ.has_value())
5977 return FoldIntoCmpYZ();
6004 return FoldIntoCmpYZ();
6013 return FoldIntoCmpYZ();
6045 const APInt *
Lo =
nullptr, *
Hi =
nullptr;
6068 I,
Builder.CreateICmp(Pred,
X, ConstantInt::get(
X->getType(),
C)));
6074 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6078 if (
I.isEquality()) {
6113 Type *Ty =
A->getType();
6114 Value *CtPop = Builder.CreateUnaryIntrinsic(Intrinsic::ctpop,
A);
6116 ConstantInt::get(Ty, 2))
6118 ConstantInt::get(Ty, 1));
6125using OffsetOp = std::pair<Instruction::BinaryOps, Value *>;
6127 bool AllowRecursion) {
6133 case Instruction::Add:
6134 Offsets.emplace_back(Instruction::Sub, Inst->
getOperand(1));
6135 Offsets.emplace_back(Instruction::Sub, Inst->
getOperand(0));
6137 case Instruction::Sub:
6138 Offsets.emplace_back(Instruction::Add, Inst->
getOperand(1));
6140 case Instruction::Xor:
6141 Offsets.emplace_back(Instruction::Xor, Inst->
getOperand(1));
6142 Offsets.emplace_back(Instruction::Xor, Inst->
getOperand(0));
6144 case Instruction::Shl:
6146 Offsets.emplace_back(Instruction::AShr, Inst->
getOperand(1));
6148 Offsets.emplace_back(Instruction::LShr, Inst->
getOperand(1));
6150 case Instruction::Select:
6151 if (AllowRecursion) {
6198 assert(
I.isEquality() &&
"Expected an equality icmp");
6199 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6210 case Instruction::AShr: {
6211 const APInt *CV, *CRHS;
6213 CV->
ashr(*CRHS).
shl(*CRHS) == *CV) &&
6219 case Instruction::LShr: {
6220 const APInt *CV, *CRHS;
6222 CV->
lshr(*CRHS).
shl(*CRHS) == *CV) &&
6241 auto ApplyOffset = [&](
Value *V,
unsigned BinOpc,
6244 if (!Sel->hasOneUse())
6246 Value *TrueVal = ApplyOffsetImpl(Sel->getTrueValue(), BinOpc,
RHS);
6249 Value *FalseVal = ApplyOffsetImpl(Sel->getFalseValue(), BinOpc,
RHS);
6254 if (
Value *Simplified = ApplyOffsetImpl(V, BinOpc,
RHS))
6259 for (
auto [BinOp,
RHS] : OffsetOps) {
6260 auto BinOpc =
static_cast<unsigned>(BinOp);
6262 auto Op0Result = ApplyOffset(Op0, BinOpc,
RHS);
6263 if (!Op0Result.isValid())
6265 auto Op1Result = ApplyOffset(Op1, BinOpc,
RHS);
6266 if (!Op1Result.isValid())
6269 Value *NewLHS = Op0Result.materialize(Builder);
6270 Value *NewRHS = Op1Result.materialize(Builder);
6271 return new ICmpInst(
I.getPredicate(), NewLHS, NewRHS);
6278 if (!
I.isEquality())
6281 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6285 if (
A == Op1 ||
B == Op1) {
6286 Value *OtherVal =
A == Op1 ?
B :
A;
6314 Value *OtherVal =
A == Op0 ?
B :
A;
6321 Value *
X =
nullptr, *
Y =
nullptr, *Z =
nullptr;
6327 }
else if (
A ==
D) {
6331 }
else if (
B ==
C) {
6335 }
else if (
B ==
D) {
6345 const APInt *C0, *C1;
6347 (*C0 ^ *C1).isNegatedPowerOf2();
6353 int(Op0->
hasOneUse()) + int(Op1->hasOneUse()) +
6355 if (XorIsNegP2 || UseCnt >= 2) {
6358 Op1 =
Builder.CreateAnd(Op1, Z);
6378 (Op0->
hasOneUse() || Op1->hasOneUse())) {
6383 MaskC->
countr_one() ==
A->getType()->getScalarSizeInBits())
6389 const APInt *AP1, *AP2;
6398 if (ShAmt < TypeBits && ShAmt != 0) {
6403 return new ICmpInst(NewPred,
Xor, ConstantInt::get(
A->getType(), CmpVal));
6413 if (ShAmt < TypeBits && ShAmt != 0) {
6433 if (ShAmt < ASize) {
6456 A->getType()->getScalarSizeInBits() ==
BitWidth * 2 &&
6457 (
I.getOperand(0)->hasOneUse() ||
I.getOperand(1)->hasOneUse())) {
6462 Add, ConstantInt::get(
A->getType(),
C.shl(1)));
6489 Builder.CreateIntrinsic(Op0->
getType(), Intrinsic::fshl, {A, A, B}));
6504 std::optional<bool> IsZero = std::nullopt;
6546 Constant *
C = ConstantInt::get(Res->X->getType(), Res->C);
6550 unsigned SrcBits =
X->getType()->getScalarSizeInBits();
6552 if (
II->getIntrinsicID() == Intrinsic::cttz ||
6553 II->getIntrinsicID() == Intrinsic::ctlz) {
6554 unsigned MaxRet = SrcBits;
6580 bool IsSignedExt = CastOp0->getOpcode() == Instruction::SExt;
6581 bool IsSignedCmp = ICmp.
isSigned();
6589 if (IsZext0 != IsZext1) {
6594 if (ICmp.
isEquality() &&
X->getType()->isIntOrIntVectorTy(1) &&
6595 Y->getType()->isIntOrIntVectorTy(1))
6605 bool IsNonNeg0 = NonNegInst0 && NonNegInst0->hasNonNeg();
6606 bool IsNonNeg1 = NonNegInst1 && NonNegInst1->hasNonNeg();
6608 if ((IsZext0 && IsNonNeg0) || (IsZext1 && IsNonNeg1))
6615 Type *XTy =
X->getType(), *YTy =
Y->getType();
6622 IsSignedExt ? Instruction::SExt : Instruction::ZExt;
6624 X =
Builder.CreateCast(CastOpcode,
X, YTy);
6626 Y =
Builder.CreateCast(CastOpcode,
Y, XTy);
6638 if (IsSignedCmp && IsSignedExt)
6651 Type *SrcTy = CastOp0->getSrcTy();
6659 if (IsSignedExt && IsSignedCmp)
6690 Value *SimplifiedOp0 = simplifyIntToPtrRoundTripCast(ICmp.
getOperand(0));
6691 Value *SimplifiedOp1 = simplifyIntToPtrRoundTripCast(ICmp.
getOperand(1));
6692 if (SimplifiedOp0 || SimplifiedOp1)
6694 SimplifiedOp0 ? SimplifiedOp0 : ICmp.
getOperand(0),
6695 SimplifiedOp1 ? SimplifiedOp1 : ICmp.
getOperand(1));
6704 Value *Op0Src = CastOp0->getOperand(0);
6705 Type *SrcTy = CastOp0->getSrcTy();
6706 Type *DestTy = CastOp0->getDestTy();
6710 auto CompatibleSizes = [&](
Type *PtrTy,
Type *IntTy) {
6711 unsigned IntWidth = IntTy->getScalarType()->getIntegerBitWidth();
6712 unsigned IndexWidth =
DL.getAddressSizeInBits(PtrTy);
6713 unsigned PtrWidth =
DL.getPointerTypeSizeInBits(PtrTy);
6716 return IntWidth == IndexWidth && IndexWidth == PtrWidth;
6720 Value *NewOp1 =
nullptr;
6722 NewOp1 = PtrToIntOp1->getOperand(0);
6725 NewOp1 = PtrToAddrOp1->getOperand(0);
6732 if ((!HasPtrToInt || CompatibleSizes(SrcTy, DestTy)) &&
6738 if (CastOp0->getOpcode() == Instruction::IntToPtr &&
6739 CompatibleSizes(DestTy, SrcTy)) {
6740 Value *NewOp1 =
nullptr;
6742 Value *IntSrc = IntToPtrOp1->getOperand(0);
6744 NewOp1 = IntToPtrOp1->getOperand(0);
6764 case Instruction::Add:
6765 case Instruction::Sub:
6767 case Instruction::Mul:
6768 return !(
RHS->getType()->isIntOrIntVectorTy(1) && IsSigned) &&
6780 case Instruction::Add:
6785 case Instruction::Sub:
6790 case Instruction::Mul:
6799 bool IsSigned,
Value *LHS,
6810 Builder.SetInsertPoint(&OrigI);
6827 Result = Builder.CreateBinOp(BinaryOp,
LHS,
RHS);
6828 Result->takeName(&OrigI);
6832 Result = Builder.CreateBinOp(BinaryOp,
LHS,
RHS);
6833 Result->takeName(&OrigI);
6837 Inst->setHasNoSignedWrap();
6839 Inst->setHasNoUnsignedWrap();
6864 const APInt *OtherVal,
6872 unsigned Opcode = Instr->getOpcode();
6873 assert(Opcode == Instruction::Add || Opcode == Instruction::Mul);
6880 Type *TyA =
A->getType(), *TyB =
B->getType();
6882 WidthB = TyB->getPrimitiveSizeInBits();
6883 unsigned ResultWidth;
6885 if (WidthB > WidthA) {
6886 ResultWidth = WidthB;
6889 ResultWidth = WidthA;
6902 unsigned TruncWidth = TI->getType()->getPrimitiveSizeInBits();
6903 if (TruncWidth > ResultWidth)
6907 if (BO->getOpcode() != Instruction::And)
6910 const APInt &CVal = CI->getValue();
6926 switch (
I.getPredicate()) {
6933 if (MaxVal.
eq(*OtherVal))
6943 if (MaxVal.
eq(*OtherVal))
6956 Value *ResultA =
A, *ResultB =
B;
6957 if (WidthA < ResultWidth)
6958 ResultA = Builder.CreateZExt(
A, ResultType);
6959 if (WidthB < ResultWidth)
6960 ResultB = Builder.CreateZExt(
B, ResultType);
6963 Value *OverflowCheck;
6965 if (Opcode == Instruction::Add) {
6967 ArithResult = Builder.CreateAdd(ResultA, ResultB,
"add");
6971 Builder.CreateICmpUGE(ArithResult, ResultA,
"not.add.overflow");
6974 Builder.CreateICmpULT(ArithResult, ResultA,
"add.overflow");
6977 Value *
Call = Builder.CreateIntrinsic(Intrinsic::umul_with_overflow,
6978 ResultType, {ResultA, ResultB},
6980 ArithResult = Builder.CreateExtractValue(
Call, 0,
"umul.value");
6981 OverflowCheck = Builder.CreateExtractValue(
Call, 1,
"umul.overflow");
6983 OverflowCheck = Builder.CreateNot(OverflowCheck);
6994 if (TI->getType()->getPrimitiveSizeInBits() == ResultWidth)
6999 assert(BO->getOpcode() == Instruction::And);
7003 Value *ShortAnd = Builder.CreateAnd(ArithResult, ShortMask);
7004 Value *Zext = Builder.CreateZExt(ShortAnd, BO->
getType());
7030 switch (
I.getPredicate()) {
7061 assert(DI && UI &&
"Instruction not defined\n");
7073 if (Usr != UI && !
DT.dominates(DB, Usr->getParent()))
7088 if (!IC || (IC->getOperand(0) !=
SI && IC->getOperand(1) !=
SI))
7135 const unsigned SIOpd) {
7136 assert((SIOpd == 1 || SIOpd == 2) &&
"Invalid select operand!");
7138 BasicBlock *Succ =
SI->getParent()->getTerminator()->getSuccessor(1);
7152 SI->replaceUsesOutsideBlock(
SI->getOperand(SIOpd),
SI->getParent());
7162 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7167 unsigned BitWidth = Ty->isIntOrIntVectorTy()
7168 ? Ty->getScalarSizeInBits()
7169 :
DL.getPointerTypeSizeInBits(Ty->getScalarType());
7193 if (
I.hasSameSign() &&
I.isUnsigned()) {
7195 if (To.isNegative() || To.isNonNegative())
7200 To.makeNonNegative();
7202 PropagateSignBit(Op0Known, Op1Known);
7203 PropagateSignBit(Op1Known, Op0Known);
7238 if (!Cmp.hasOneUse())
7247 if (!isMinMaxCmp(
I)) {
7252 if (Op1Min == Op0Max)
7257 if (*CmpC == Op0Min + 1)
7259 ConstantInt::get(Op1->getType(), *CmpC - 1));
7269 if (Op1Max == Op0Min)
7274 if (*CmpC == Op0Max - 1)
7276 ConstantInt::get(Op1->getType(), *CmpC + 1));
7286 if (Op1Min == Op0Max)
7290 if (*CmpC == Op0Min + 1)
7292 ConstantInt::get(Op1->getType(), *CmpC - 1));
7297 if (Op1Max == Op0Min)
7301 if (*CmpC == Op0Max - 1)
7303 ConstantInt::get(Op1->getType(), *CmpC + 1));
7320 APInt Op0KnownZeroInverted = ~Op0Known.Zero;
7323 Value *LHS =
nullptr;
7326 *LHSC != Op0KnownZeroInverted)
7332 Type *XTy =
X->getType();
7334 APInt C2 = Op0KnownZeroInverted;
7335 APInt C2Pow2 = (C2 & ~(*C1 - 1)) + *C1;
7341 auto *CmpC = ConstantInt::get(XTy, Log2C2 - Log2C1);
7351 (Op0Known & Op1Known) == Op0Known)
7357 if (Op1Min == Op0Max)
7361 if (Op1Max == Op0Min)
7365 if (Op1Min == Op0Max)
7369 if (Op1Max == Op0Min)
7377 if ((
I.isSigned() || (
I.isUnsigned() && !
I.hasSameSign())) &&
7380 I.setPredicate(
I.getUnsignedPredicate());
7398 return BinaryOperator::CreateAnd(
Builder.CreateIsNull(
X),
Y);
7404 return BinaryOperator::CreateOr(
Builder.CreateIsNull(
X),
Y);
7415 bool IsSExt = ExtI->
getOpcode() == Instruction::SExt;
7417 auto CreateRangeCheck = [&] {
7432 }
else if (!IsSExt || HasOneUse) {
7437 return CreateRangeCheck();
7439 }
else if (IsSExt ?
C->isAllOnes() :
C->isOne()) {
7447 }
else if (!IsSExt || HasOneUse) {
7452 return CreateRangeCheck();
7466 Instruction::ICmp, Pred1,
X,
7485 Value *Op0 =
I.getOperand(0);
7486 Value *Op1 =
I.getOperand(1);
7492 if (!FlippedStrictness)
7496 new ICmpInst(FlippedStrictness->first, Op0, FlippedStrictness->second);
7497 NewCmp->setSameSign(FlippedStrictness->first.hasSameSign());
7516 I.setName(
I.getName() +
".not");
7527 Value *
A =
I.getOperand(0), *
B =
I.getOperand(1);
7528 assert(
A->getType()->isIntOrIntVectorTy(1) &&
"Bools only");
7534 switch (
I.getPredicate()) {
7543 switch (
I.getPredicate()) {
7553 switch (
I.getPredicate()) {
7562 return BinaryOperator::CreateXor(
A,
B);
7570 return BinaryOperator::CreateAnd(Builder.CreateNot(
A),
B);
7578 return BinaryOperator::CreateAnd(Builder.CreateNot(
B),
A);
7586 return BinaryOperator::CreateOr(Builder.CreateNot(
A),
B);
7594 return BinaryOperator::CreateOr(Builder.CreateNot(
B),
A);
7642 Value *NewX = Builder.CreateLShr(
X,
Y,
X->getName() +
".highbits");
7650 Value *
LHS = Cmp.getOperand(0), *
RHS = Cmp.getOperand(1);
7654 Value *V = Builder.CreateCmp(Pred,
X,
Y, Cmp.getName());
7656 I->copyIRFlags(&Cmp);
7657 Module *M = Cmp.getModule();
7659 M, Intrinsic::vector_reverse, V->getType());
7666 (
LHS->hasOneUse() ||
RHS->hasOneUse()))
7667 return createCmpReverse(Pred,
V1, V2);
7671 return createCmpReverse(Pred,
V1,
RHS);
7675 return createCmpReverse(Pred,
LHS, V2);
7684 Type *V1Ty =
V1->getType();
7686 V1Ty == V2->
getType() && (
LHS->hasOneUse() ||
RHS->hasOneUse())) {
7687 Value *NewCmp = Builder.CreateCmp(Pred,
V1, V2);
7700 Constant *ScalarC =
C->getSplatValue(
true);
7708 Value *NewCmp = Builder.CreateCmp(Pred,
V1,
C);
7719 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7725 if (
match(Op0, UAddOvResultPat) &&
7736 (Op0 ==
A || Op0 ==
B))
7746 if (!
I.getOperand(0)->getType()->isPointerTy() ||
7748 I.getParent()->getParent(),
7749 I.getOperand(0)->getType()->getPointerAddressSpace())) {
7753 if (
match(
I.getOperand(0),
7769 Value *Const =
I.getOperand(1);
7787 Type *VecEltTy = VecTy->getElementType();
7789 DL.getTypeSizeInBits(VecEltTy) * VecTy->getNumElements();
7790 if (!
DL.fitsInLegalInteger(ScalarBW))
7794 ? ConstantInt::get(ScalarTy, 0)
7797 Builder.CreateBitCast(Vec, ScalarTy), NewConst);
7809 if (
I.getType()->isVectorTy())
7832 if (!LHSTy || !LHSTy->getElementType()->isIntegerTy())
7835 LHSTy->getNumElements() * LHSTy->getElementType()->getIntegerBitWidth();
7837 if (!
DL.isLegalInteger(NumBits))
7841 auto *ScalarTy = Builder.getIntNTy(NumBits);
7842 LHS = Builder.CreateBitCast(
LHS, ScalarTy,
LHS->getName() +
".scalar");
7843 RHS = Builder.CreateBitCast(
RHS, ScalarTy,
RHS->getName() +
".scalar");
7899 bool IsIntMinPosion =
C->isAllOnesValue();
7911 CtxI, IsIntMinPosion
7912 ?
Builder.CreateICmpSGT(
X, AllOnesValue)
7914 X, ConstantInt::get(
X->getType(),
SMin + 1)));
7920 CtxI, IsIntMinPosion
7921 ?
Builder.CreateICmpSLT(
X, NullValue)
7923 X, ConstantInt::get(
X->getType(),
SMin)));
7950 auto CheckUGT1 = [](
const APInt &Divisor) {
return Divisor.ugt(1); };
7965 auto CheckNE0 = [](
const APInt &Shift) {
return !Shift.isZero(); };
7986 if (ShAmt >=
X->getType()->getScalarSizeInBits())
7988 if (canEvaluateShifted(Op1, ShAmt,
false,
7990 Value *NewOp1 = getShiftedValue(Op1, ShAmt,
false,
7998 if (ShAmt >=
X->getType()->getScalarSizeInBits())
8000 if (canEvaluateShifted(Op1, ShAmt,
false,
8002 Value *NewOp1 = getShiftedValue(Op1, ShAmt,
false,
8013 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
8020 if (Op0Cplxity < Op1Cplxity) {
8035 if (
Value *V = dyn_castNegVal(SelectTrue)) {
8036 if (V == SelectFalse)
8038 }
else if (
Value *V = dyn_castNegVal(SelectFalse)) {
8039 if (V == SelectTrue)
8099 if (
C->isNonNegative())
8103 ConstantInt::get(
X->getType(), ~*
C));
8109 if (
C->isNonNegative())
8113 ConstantInt::get(
X->getType(), ~*
C));
8169 if (
I.isCommutative()) {
8170 if (
auto Pair = matchSymmetricPair(
I.getOperand(0),
I.getOperand(1))) {
8199 (Op0->
hasOneUse() || Op1->hasOneUse())) {
8227 bool I0NUW = I0->hasNoUnsignedWrap();
8228 bool I1NUW = I1->hasNoUnsignedWrap();
8229 bool I0NSW = I0->hasNoSignedWrap();
8230 bool I1NSW = I1->hasNoSignedWrap();
8234 ((I0NUW || I0NSW) && (I1NUW || I1NSW)))) {
8236 ConstantInt::get(Op0->
getType(), 0));
8243 assert(Op1->getType()->isPointerTy() &&
8244 "Comparing pointer with non-pointer?");
8268 Type *SmallType =
X->getType();
8270 if (Mask->isMask(SmallWidth) &&
8271 shouldChangeType(
I.getOperand(0)->getType(), SmallType)) {
8273 return new ICmpInst(
I.getUnsignedPredicate(), NewTrunc,
X);
8291 bool ConsumesOp0, ConsumesOp1;
8294 (ConsumesOp0 || ConsumesOp1)) {
8297 assert(InvOp0 && InvOp1 &&
8298 "Mismatch between isFreeToInvert and getFreelyInverted");
8299 return new ICmpInst(
I.getSwappedPredicate(), InvOp0, InvOp1);
8311 if (AddI->
getOpcode() == Instruction::Add &&
8312 OptimizeOverflowCheck(Instruction::Add,
false,
X,
Y, *AddI,
8313 Result, Overflow)) {
8333 if ((
I.isUnsigned() ||
I.isEquality()) &&
8336 Y->getType()->getScalarSizeInBits() == 1 &&
8337 (Op0->
hasOneUse() || Op1->hasOneUse())) {
8344 unsigned ShiftOpc = ShiftI->
getOpcode();
8345 if ((ExtOpc == Instruction::ZExt && ShiftOpc == Instruction::LShr) ||
8346 (ExtOpc == Instruction::SExt && ShiftOpc == Instruction::AShr)) {
8380 if (EVI->getIndices()[0] == 0 && ACXI->getCompareOperand() == Op1 &&
8387 if (
I.getType()->isVectorTy())
8399 const APInt *C1, *C2;
8406 Type *InputTy =
A->getType();
8413 TruncC1.
setBit(InputBitWidth - 1);
8417 ConstantInt::get(InputTy, C2->
trunc(InputBitWidth)));
8437 if (MantissaWidth == -1)
8444 if (
I.isEquality()) {
8446 bool IsExact =
false;
8447 APSInt RHSCvt(IntWidth, LHSUnsigned);
8456 if (*RHS != RHSRoundInt) {
8476 if ((
int)IntWidth > MantissaWidth) {
8478 int Exp =
ilogb(*RHS);
8481 if (MaxExponent < (
int)IntWidth - !LHSUnsigned)
8487 if (MantissaWidth <= Exp && Exp <= (
int)IntWidth - !LHSUnsigned)
8496 assert(!RHS->isNaN() &&
"NaN comparison not already folded!");
8499 switch (
I.getPredicate()) {
8590 APSInt RHSInt(IntWidth, LHSUnsigned);
8593 if (!RHS->isZero()) {
8608 if (RHS->isNegative())
8614 if (RHS->isNegative())
8620 if (RHS->isNegative())
8627 if (!RHS->isNegative())
8633 if (RHS->isNegative())
8639 if (RHS->isNegative())
8645 if (RHS->isNegative())
8652 if (!RHS->isNegative())
8671 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
8682 unsigned Pred =
I.getPredicate();
8690 if (!Res00 || !Res01 || !Res10 || !Res11)
8699 std::bitset<4>
Table;
8757 if (
C->isNegative())
8758 Pred =
I.getSwappedPredicate();
8785 "X ord/uno NaN should be folded away by simplifyFCmpInst()");
8791 bool RoundDown =
false;
8812 auto NextValue = [](
const APFloat &
Value,
bool RoundDown) {
8814 NextValue.
next(RoundDown);
8818 APFloat NextCValue = NextValue(*CValue, RoundDown);
8823 APFloat ExtCValue = ConvertFltSema(*CValue, DestFltSema);
8824 APFloat ExtNextCValue = ConvertFltSema(NextCValue, DestFltSema);
8831 APFloat PrevCValue = NextValue(*CValue, !RoundDown);
8832 APFloat Bias = ConvertFltSema(*CValue - PrevCValue, DestFltSema);
8834 ExtNextCValue = ExtCValue + Bias;
8841 C.getType()->getScalarType()->getFltSemantics();
8844 APFloat MidValue = ConvertFltSema(ExtMidValue, SrcFltSema);
8845 if (MidValue != *CValue)
8846 ExtMidValue.
next(!RoundDown);
8854 if (ConvertFltSema(ExtMidValue, SrcFltSema).isInfinity())
8858 APFloat NextExtMidValue = NextValue(ExtMidValue, RoundDown);
8859 if (ConvertFltSema(NextExtMidValue, SrcFltSema).
isFinite())
8864 ConstantFP::get(DestType, ExtMidValue),
"", &
I);
8877 if (!
C->isPosZero()) {
8878 if (!
C->isSmallestNormalized())
8891 switch (
I.getPredicate()) {
8917 switch (
I.getPredicate()) {
8942 assert(!
I.hasNoNaNs() &&
"fcmp should have simplified");
8947 assert(!
I.hasNoNaNs() &&
"fcmp should have simplified");
8961 return replacePredAndOp0(&
I,
I.getPredicate(),
X);
8984 I.setHasNoInfs(
false);
8986 switch (
I.getPredicate()) {
9031 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
9036 Pred =
I.getSwappedPredicate();
9045 return new FCmpInst(Pred, Op0, Zero,
"", &
I);
9081 I.getFunction()->getDenormalMode(
9088 I.setHasNoNaNs(
true);
9113 if (MantissaWidth != -1 &&
ilogb(*
C) < MantissaWidth) {
9115 I.setPredicate(
I.getSwappedPredicate());
9152 if (!IsStrictLt && !IsStrictGt && !IsGe)
9174 }
else if (
match(FAbsArg,
9182 if (
A->getType() !=
B->getType())
9197 Type *OpType =
LHS->getType();
9203 if (!FloorX && !CeilX) {
9207 Pred =
I.getSwappedPredicate();
9283 if (!
I || !(
I->getOpcode() == Instruction::SIToFP ||
9284 I->getOpcode() == Instruction::UIToFP))
9287 bool IsUnsigned =
I->getOpcode() == Instruction::UIToFP;
9288 unsigned BitWidth =
I->getOperand(0)->getType()->getScalarSizeInBits();
9311 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
9313 SQ.getWithInstruction(&
I)))
9318 assert(OpType == Op1->getType() &&
"fcmp with different-typed operands?");
9343 if (
I.isCommutative()) {
9344 if (
auto Pair = matchSymmetricPair(
I.getOperand(0),
I.getOperand(1))) {
9366 return new FCmpInst(
I.getSwappedPredicate(),
X,
Y,
"", &
I);
9382 bool IsRedundantMinMaxClamp =
9444 X->getType()->isIntOrIntVectorTy() &&
9445 !
F.getDenormalMode(Op1->getType()->getScalarType()->getFltSemantics())
9446 .inputsMayBeZero()) {
9454 Type *IntTy =
X->getType();
9455 const APInt &SignMask =
~APInt::getSignMask(IntTy->getScalarSizeInBits());
9456 Value *MaskX =
Builder.CreateAnd(
X, ConstantInt::get(IntTy, SignMask));
9466 case Instruction::Select:
9474 case Instruction::FSub:
9479 case Instruction::PHI:
9483 case Instruction::SIToFP:
9484 case Instruction::UIToFP:
9488 case Instruction::FDiv:
9492 case Instruction::Load:
9498 case Instruction::FPTrunc:
9525 return new FCmpInst(
I.getSwappedPredicate(),
X, NegC,
"", &
I);
9539 X->getType() ==
Y->getType())
9550 X->getType()->getScalarType()->getFltSemantics();
9586 Constant *NewC = ConstantFP::get(
X->getType(), TruncC);
9599 Type *IntType =
Builder.getIntNTy(
X->getType()->getScalarSizeInBits());
9612 Value *CanonLHS =
nullptr;
9615 if (CanonLHS == Op1)
9616 return new FCmpInst(Pred, Op1, Op1,
"", &
I);
9618 Value *CanonRHS =
nullptr;
9621 if (CanonRHS == Op0)
9622 return new FCmpInst(Pred, Op0, Op0,
"", &
I);
9625 if (CanonLHS && CanonRHS)
9626 return new FCmpInst(Pred, CanonLHS, CanonRHS,
"", &
I);
9629 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 a class to represent arbitrary precision integral constant values and operations...
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 * 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 * foldCmpLoadFromIndexedGlobal(LoadInst *LI, GetElementPtrInst *GEP, CmpPredicate Pred, Constant *RHSC, Instruction &CtxI, ConstantInt *AndCst=nullptr)
This is called when we see this pattern: cmp pred (load (gep GV, ...)), cmpcst where GV is a global v...
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
Module & getModule() 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)
is_zero< true > m_Zero()
Match any null constant or a vector with all elements equal to 0.
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.
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 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.
@ End
Run the machine verifier once, at the end of the pipeline.
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.
LLVM_ABI SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr)
Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind and providing the out param...
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.