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()) {
123 if (LI->
isVolatile() || !GV || !GV->isConstant() ||
124 !GV->hasDefinitiveInitializer())
128 TypeSize EltSize =
DL.getTypeStoreSize(EltTy);
144 if (!ConstOffset.
ult(Stride))
152 uint64_t ArrayElementCount =
155 if (ArrayElementCount >
CLOpts.maxarray_size)
158 enum { Overdefined = -3, Undefined = -2 };
167 int FirstTrueElement = Undefined, SecondTrueElement = Undefined;
171 int FirstFalseElement = Undefined, SecondFalseElement = Undefined;
179 int TrueRangeEnd = Undefined, FalseRangeEnd = Undefined;
184 uint64_t MagicBitvector = 0;
189 for (
unsigned i = 0, e = ArrayElementCount; i != e; ++i,
Offset += Stride) {
203 CompareRHS,
DL, &
TLI);
211 if (TrueRangeEnd == (
int)i - 1)
213 if (FalseRangeEnd == (
int)i - 1)
230 if (FirstTrueElement == Undefined)
231 FirstTrueElement = TrueRangeEnd = i;
234 if (SecondTrueElement == Undefined)
235 SecondTrueElement = i;
237 SecondTrueElement = Overdefined;
240 if (TrueRangeEnd == (
int)i - 1)
243 TrueRangeEnd = Overdefined;
247 if (FirstFalseElement == Undefined)
248 FirstFalseElement = FalseRangeEnd = i;
251 if (SecondFalseElement == Undefined)
252 SecondFalseElement = i;
254 SecondFalseElement = Overdefined;
257 if (FalseRangeEnd == (
int)i - 1)
260 FalseRangeEnd = Overdefined;
265 if (i < 64 && IsTrueForElt)
266 MagicBitvector |= 1ULL << i;
271 if ((i & 8) == 0 && i >= 64 && SecondTrueElement == Overdefined &&
272 SecondFalseElement == Overdefined && TrueRangeEnd == Overdefined &&
273 FalseRangeEnd == Overdefined)
287 auto MaskIdx = [&](
Value *Idx) {
291 Idx =
Builder.CreateAnd(Idx, Mask);
298 if (SecondTrueElement != Overdefined) {
301 if (FirstTrueElement == Undefined)
304 Value *FirstTrueIdx = ConstantInt::get(Idx->
getType(), FirstTrueElement);
307 if (SecondTrueElement == Undefined)
312 Value *SecondTrueIdx = ConstantInt::get(Idx->
getType(), SecondTrueElement);
314 return BinaryOperator::CreateOr(C1, C2);
319 if (SecondFalseElement != Overdefined) {
322 if (FirstFalseElement == Undefined)
325 Value *FirstFalseIdx = ConstantInt::get(Idx->
getType(), FirstFalseElement);
328 if (SecondFalseElement == Undefined)
333 Value *SecondFalseIdx =
334 ConstantInt::get(Idx->
getType(), SecondFalseElement);
336 return BinaryOperator::CreateAnd(C1, C2);
341 if (TrueRangeEnd != Overdefined) {
342 assert(TrueRangeEnd != FirstTrueElement &&
"Should emit single compare");
346 if (FirstTrueElement) {
348 Idx =
Builder.CreateAdd(Idx, Offs);
352 ConstantInt::get(Idx->
getType(), TrueRangeEnd - FirstTrueElement + 1);
357 if (FalseRangeEnd != Overdefined) {
358 assert(FalseRangeEnd != FirstFalseElement &&
"Should emit single compare");
361 if (FirstFalseElement) {
363 Idx =
Builder.CreateAdd(Idx, Offs);
367 ConstantInt::get(Idx->
getType(), FalseRangeEnd - FirstFalseElement);
380 if (ArrayElementCount <= Idx->
getType()->getIntegerBitWidth())
383 Ty =
DL.getSmallestLegalIntType(
Init->getContext(), ArrayElementCount);
388 V =
Builder.CreateLShr(ConstantInt::get(Ty, MagicBitvector), V);
389 V =
Builder.CreateAnd(ConstantInt::get(Ty, 1), V);
414 while (!WorkList.
empty()) {
417 while (!WorkList.
empty()) {
418 if (Explored.
size() >= 100)
436 if (!
GEP->isInBounds() ||
count_if(
GEP->indices(), IsNonConst) > 1)
444 if (WorkList.
back() == V) {
460 for (
auto *PN : PHIs)
461 for (
Value *
Op : PN->incoming_values())
469 for (
Value *Val : Explored) {
475 if (Inst ==
Base || Inst ==
PHI || !Inst || !
PHI ||
479 if (
PHI->getParent() == Inst->getParent())
489 bool Before =
true) {
497 I = &*std::next(
I->getIterator());
498 Builder.SetInsertPoint(
I);
503 BasicBlock &Entry =
A->getParent()->getEntryBlock();
504 Builder.SetInsertPoint(Entry.getFirstInsertionPt());
526 Base->getContext(),
DL.getIndexTypeSizeInBits(Start->getType()));
532 for (
Value *Val : Explored) {
540 PHI->getName() +
".idx",
PHI->getIterator());
545 for (
Value *Val : Explored) {
554 NewInsts[
GEP] = OffsetV;
556 NewInsts[
GEP] = Builder.CreateAdd(
557 Op, OffsetV,
GEP->getOperand(0)->getName() +
".add",
569 for (
Value *Val : Explored) {
576 for (
unsigned I = 0,
E =
PHI->getNumIncomingValues();
I <
E; ++
I) {
577 Value *NewIncoming =
PHI->getIncomingValue(
I);
579 auto It = NewInsts.
find(NewIncoming);
580 if (It != NewInsts.
end())
581 NewIncoming = It->second;
588 for (
Value *Val : Explored) {
594 Value *NewVal = Builder.CreateGEP(Builder.getInt8Ty(),
Base, NewInsts[Val],
595 Val->getName() +
".ptr", NW);
602 return NewInsts[Start];
688 if (
Base.Ptr == RHS && CanFold(
Base.LHSNW) && !
Base.isExpensive()) {
692 EmitGEPOffsets(
Base.LHSGEPs,
Base.LHSNW, IdxTy,
true);
700 RHS->getType()->getPointerAddressSpace())) {
731 if (GEPLHS->
getOperand(0) != GEPRHS->getOperand(0)) {
732 bool IndicesTheSame =
735 GEPRHS->getPointerOperand()->getType() &&
739 if (GEPLHS->
getOperand(i) != GEPRHS->getOperand(i)) {
740 IndicesTheSame =
false;
746 if (IndicesTheSame &&
754 if (GEPLHS->
isInBounds() && GEPRHS->isInBounds() &&
756 (GEPRHS->hasAllConstantIndices() || GEPRHS->hasOneUse()) &&
760 Value *LOffset = EmitGEPOffset(GEPLHS);
761 Value *ROffset = EmitGEPOffset(GEPRHS);
768 if (LHSIndexTy != RHSIndexTy) {
771 ROffset =
Builder.CreateTrunc(ROffset, LHSIndexTy);
773 LOffset =
Builder.CreateTrunc(LOffset, RHSIndexTy);
782 if (GEPLHS->
getOperand(0) == GEPRHS->getOperand(0) &&
786 unsigned NumDifferences = 0;
787 unsigned DiffOperand = 0;
788 for (
unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i)
789 if (GEPLHS->
getOperand(i) != GEPRHS->getOperand(i)) {
791 Type *RHSType = GEPRHS->getOperand(i)->getType();
802 if (NumDifferences++)
807 if (NumDifferences == 0)
815 Value *RHSV = GEPRHS->getOperand(DiffOperand);
816 return NewICmp(NW, LHSV, RHSV);
820 if (
Base.Ptr && !
Base.isExpensive()) {
822 bool DoFold = CanFold(
Base.LHSNW &
Base.RHSNW);
824 if (!DoFold &&
Base.Ptr->getType()->isPointerTy()) {
828 unsigned BW =
DL.getIndexTypeSizeInBits(GEPLHS->
getType());
833 DL, LOff,
true) ==
Base.Ptr &&
834 RHS->stripAndAccumulateConstantOffsets(
835 DL, ROff,
true) ==
Base.Ptr)
847 return NewICmp(
Base.LHSNW &
Base.RHSNW, L, R);
874 bool Captured =
false;
879 CmpCaptureTracker(
AllocaInst *Alloca) : Alloca(Alloca) {}
881 void tooManyUses()
override { Captured =
true; }
893 ICmps[ICmp] |= 1u << U->getOperandNo();
902 CmpCaptureTracker Tracker(Alloca);
904 if (Tracker.Captured)
908 for (
auto [ICmp,
Operands] : Tracker.ICmps) {
914 auto *Res = ConstantInt::get(ICmp->getType(),
940 assert(!!
C &&
"C should not be zero!");
956 ConstantInt::get(
X->getType(), -
C));
968 ConstantInt::get(
X->getType(),
SMax -
C));
979 ConstantInt::get(
X->getType(),
SMax - (
C - 1)));
988 assert(
I.isEquality() &&
"Cannot fold icmp gt/lt");
991 if (
I.getPredicate() ==
I.ICMP_NE)
993 return new ICmpInst(Pred, LHS, RHS);
1012 return getICmp(
I.ICMP_UGT,
A,
1013 ConstantInt::get(
A->getType(), AP2.
logBase2()));
1025 if (IsAShr && AP1 == AP2.
ashr(Shift)) {
1029 return getICmp(
I.ICMP_UGE,
A, ConstantInt::get(
A->getType(), Shift));
1030 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1031 }
else if (AP1 == AP2.
lshr(Shift)) {
1032 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1038 auto *TorF = ConstantInt::get(
I.getType(),
I.getPredicate() ==
I.ICMP_NE);
1047 assert(
I.isEquality() &&
"Cannot fold icmp gt/lt");
1050 if (
I.getPredicate() ==
I.ICMP_NE)
1052 return new ICmpInst(Pred, LHS, RHS);
1061 if (!AP1 && AP2TrailingZeros != 0)
1064 ConstantInt::get(
A->getType(), AP2.
getBitWidth() - AP2TrailingZeros));
1072 if (Shift > 0 && AP2.
shl(Shift) == AP1)
1073 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1077 auto *TorF = ConstantInt::get(
I.getType(),
I.getPredicate() ==
I.ICMP_NE);
1106 if (NewWidth != 7 && NewWidth != 15 && NewWidth != 31)
1130 if (U == AddWithCst)
1148 I.getModule(), Intrinsic::sadd_with_overflow, NewType);
1156 Value *TruncA = Builder.CreateTrunc(
A, NewType,
A->getName() +
".trunc");
1157 Value *TruncB = Builder.CreateTrunc(
B, NewType,
B->getName() +
".trunc");
1158 CallInst *
Call = Builder.CreateCall(
F, {TruncA, TruncB},
"sadd");
1159 Value *
Add = Builder.CreateExtractValue(
Call, 0,
"sadd.result");
1177 if (!
I.isEquality())
1208 APInt(XBitWidth, XBitWidth - 1))))
1235 return new ICmpInst(Pred,
B, Cmp.getOperand(1));
1237 return new ICmpInst(Pred,
A, Cmp.getOperand(1));
1254 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1266 return new ICmpInst(Pred,
Y, Cmp.getOperand(1));
1272 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1275 if (BO0->hasNoUnsignedWrap() || BO0->hasNoSignedWrap()) {
1283 return new ICmpInst(Pred,
Y, Cmp.getOperand(1));
1288 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1304 return new ICmpInst(Pred, Stripped,
1317 const APInt *Mask, *Neg;
1333 auto *NewAnd =
Builder.CreateAnd(Num, *Mask);
1336 return new ICmpInst(Pred, NewAnd, Zero);
1357 Value *Op0 = Cmp.getOperand(0), *Op1 = Cmp.getOperand(1);
1373 for (
Value *V : Phi->incoming_values()) {
1381 PHINode *NewPhi =
Builder.CreatePHI(Cmp.getType(), Phi->getNumOperands());
1382 for (
auto [V, Pred] :
zip(
Ops, Phi->blocks()))
1397 Value *
X = Cmp.getOperand(0), *
Y = Cmp.getOperand(1);
1430 if (Cmp.isEquality() || (IsSignBit &&
hasBranchUse(Cmp)))
1435 if (Cmp.hasOneUse() &&
1449 if (!
match(BI->getCondition(),
1454 if (
DT.dominates(Edge0, Cmp.getParent())) {
1455 if (
auto *V = handleDomCond(DomPred, DomC))
1459 if (
DT.dominates(Edge1, Cmp.getParent()))
1475 Type *SrcTy =
X->getType();
1477 SrcBits = SrcTy->getScalarSizeInBits();
1481 if (shouldChangeType(Trunc->
getType(), SrcTy)) {
1483 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy,
C.sext(SrcBits)));
1485 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy,
C.zext(SrcBits)));
1488 if (
C.isOne() &&
C.getBitWidth() > 1) {
1493 ConstantInt::get(V->getType(), 1));
1505 auto NewPred = (Pred == Cmp.ICMP_EQ) ? Cmp.ICMP_UGE : Cmp.ICMP_ULT;
1507 ConstantInt::get(SrcTy, DstBits - Pow2->
logBase2()));
1513 Pred,
Y, ConstantInt::get(SrcTy,
C.logBase2() - Pow2->
logBase2()));
1519 if (!SrcTy->isVectorTy() && shouldChangeType(DstBits, SrcBits)) {
1523 Constant *WideC = ConstantInt::get(SrcTy,
C.zext(SrcBits));
1532 if ((
Known.Zero |
Known.One).countl_one() >= SrcBits - DstBits) {
1534 APInt NewRHS =
C.zext(SrcBits);
1536 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy, NewRHS));
1548 DstBits == SrcBits - ShAmt) {
1565 bool YIsSExt =
false;
1568 unsigned NoWrapFlags =
cast<TruncInst>(Cmp.getOperand(0))->getNoWrapKind() &
1570 if (Cmp.isSigned()) {
1581 if (
X->getType() !=
Y->getType() &&
1582 (!Cmp.getOperand(0)->hasOneUse() || !Cmp.getOperand(1)->hasOneUse()))
1584 if (!isDesirableIntType(
X->getType()->getScalarSizeInBits()) &&
1585 isDesirableIntType(
Y->getType()->getScalarSizeInBits())) {
1587 Pred = Cmp.getSwappedPredicate(Pred);
1592 else if (!Cmp.isSigned() &&
1606 Type *TruncTy = Cmp.getOperand(0)->getType();
1611 if (isDesirableIntType(TruncBits) &&
1612 !isDesirableIntType(
X->getType()->getScalarSizeInBits()))
1635 bool TrueIfSigned =
false;
1652 if (
Xor->hasOneUse()) {
1654 if (!Cmp.isEquality() && XorC->
isSignMask()) {
1655 Pred = Cmp.getFlippedSignednessPredicate();
1656 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(),
C ^ *XorC));
1661 Pred = Cmp.getFlippedSignednessPredicate();
1662 Pred = Cmp.getSwappedPredicate(Pred);
1663 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(),
C ^ *XorC));
1670 if (*XorC == ~
C && (
C + 1).isPowerOf2())
1673 if (*XorC ==
C && (
C + 1).isPowerOf2())
1678 if (*XorC == -
C &&
C.isPowerOf2())
1680 ConstantInt::get(
X->getType(), ~
C));
1682 if (*XorC ==
C && (-
C).isPowerOf2())
1684 ConstantInt::get(
X->getType(), ~
C));
1706 const APInt *ShiftC;
1711 Type *XType =
X->getType();
1717 return new ICmpInst(Pred,
Add, ConstantInt::get(XType, Bound));
1726 if (!Shift || !Shift->
isShift())
1734 unsigned ShiftOpcode = Shift->
getOpcode();
1735 bool IsShl = ShiftOpcode == Instruction::Shl;
1738 APInt NewAndCst, NewCmpCst;
1739 bool AnyCmpCstBitsShiftedOut;
1740 if (ShiftOpcode == Instruction::Shl) {
1748 NewCmpCst = C1.
lshr(*C3);
1749 NewAndCst = C2.
lshr(*C3);
1750 AnyCmpCstBitsShiftedOut = NewCmpCst.
shl(*C3) != C1;
1751 }
else if (ShiftOpcode == Instruction::LShr) {
1756 NewCmpCst = C1.
shl(*C3);
1757 NewAndCst = C2.
shl(*C3);
1758 AnyCmpCstBitsShiftedOut = NewCmpCst.
lshr(*C3) != C1;
1764 assert(ShiftOpcode == Instruction::AShr &&
"Unknown shift opcode");
1765 NewCmpCst = C1.
shl(*C3);
1766 NewAndCst = C2.
shl(*C3);
1767 AnyCmpCstBitsShiftedOut = NewCmpCst.
ashr(*C3) != C1;
1768 if (NewAndCst.
ashr(*C3) != C2)
1772 if (AnyCmpCstBitsShiftedOut) {
1782 Shift->
getOperand(0), ConstantInt::get(
And->getType(), NewAndCst));
1783 return new ICmpInst(Cmp.getPredicate(), NewAnd,
1784 ConstantInt::get(
And->getType(), NewCmpCst));
1801 return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
1815 return new TruncInst(
And->getOperand(0), Cmp.getType());
1826 ConstantInt::get(
X->getType(), ~*C2));
1831 ConstantInt::get(
X->getType(), -*C2));
1834 if (!
And->hasOneUse())
1837 if (Cmp.isEquality() && C1.
isZero()) {
1855 Constant *NegBOC = ConstantInt::get(
And->getType(), -NewC2);
1857 return new ICmpInst(NewPred,
X, NegBOC);
1875 if (!Cmp.getType()->isVectorTy()) {
1876 Type *WideType = W->getType();
1878 Constant *ZextC1 = ConstantInt::get(WideType, C1.
zext(WideScalarBits));
1879 Constant *ZextC2 = ConstantInt::get(WideType, C2->
zext(WideScalarBits));
1881 return new ICmpInst(Cmp.getPredicate(), NewAnd, ZextC1);
1892 if (!Cmp.isSigned() && C1.
isZero() &&
And->getOperand(0)->hasOneUse() &&
1899 unsigned UsesRemoved = 0;
1900 if (
And->hasOneUse())
1902 if (
Or->hasOneUse())
1909 if (UsesRemoved >= RequireUsesRemoved) {
1913 One,
Or->getName());
1915 return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
1929 if (!Cmp.getParent()->getParent()->hasFnAttribute(
1930 Attribute::NoImplicitFloat) &&
1933 Type *FPType = V->getType()->getScalarType();
1934 if (FPType->isIEEELikeFPTy() && (C1.
isZero() || C1 == *C2)) {
1935 APInt ExponentMask =
1937 if (*C2 == ExponentMask) {
1938 unsigned Mask = C1.
isZero()
1972 Constant *MinSignedC = ConstantInt::get(
1976 return new ICmpInst(NewPred,
X, MinSignedC);
1991 if (!Cmp.isEquality())
2001 if (
C.getBitWidth() > 1 && (
C.isZero() ||
C.isOne()) &&
2005 return new ICmpInst(Pred, MatchedX, Cmp.getOperand(1));
2009 return new TruncInst(MatchedX, Cmp.getType());
2013 if (
And->hasOneUse()) {
2014 Value *Trunc =
Builder.CreateTrunc(MatchedX, Cmp.getType());
2022 if (Cmp.getOperand(1) ==
Y &&
C.isNegatedPowerOf2()) {
2033 X->getType()->isIntOrIntVectorTy(1) && (
C.isZero() ||
C.isOne())) {
2039 return BinaryOperator::CreateAnd(TruncY,
X);
2057 const APInt *Addend, *Msk;
2061 APInt NewComperand = (
C - *Addend) & *Msk;
2062 Value *MaskA =
Builder.CreateAnd(
A, ConstantInt::get(
A->getType(), *Msk));
2064 ConstantInt::get(MaskA->
getType(), NewComperand));
2086 while (!WorkList.
empty()) {
2087 auto MatchOrOperatorArgument = [&](
Value *OrOperatorArgument) {
2090 if (
match(OrOperatorArgument,
2096 if (
match(OrOperatorArgument,
2106 Value *OrOperatorLhs, *OrOperatorRhs;
2108 if (!
match(CurrentValue,
2113 MatchOrOperatorArgument(OrOperatorRhs);
2114 MatchOrOperatorArgument(OrOperatorLhs);
2119 Value *LhsCmp = Builder.CreateICmp(Pred, CmpValues.
rbegin()->first,
2120 CmpValues.
rbegin()->second);
2122 for (
auto It = CmpValues.
rbegin() + 1; It != CmpValues.
rend(); ++It) {
2123 Value *RhsCmp = Builder.CreateICmp(Pred, It->first, It->second);
2124 LhsCmp = Builder.CreateBinOp(BOpc, LhsCmp, RhsCmp);
2140 ConstantInt::get(V->getType(), 1));
2143 Value *OrOp0 =
Or->getOperand(0), *OrOp1 =
Or->getOperand(1);
2150 Builder.CreateXor(OrOp1, ConstantInt::get(OrOp1->getType(),
C));
2151 return new ICmpInst(Pred, OrOp0, NewC);
2155 if (
match(OrOp1,
m_APInt(MaskC)) && Cmp.isEquality()) {
2156 if (*MaskC ==
C && (
C + 1).isPowerOf2()) {
2161 return new ICmpInst(Pred, OrOp0, OrOp1);
2168 if (
Or->hasOneUse()) {
2170 Constant *NewC = ConstantInt::get(
Or->getType(),
C ^ (*MaskC));
2182 Constant *NewC = ConstantInt::get(
X->getType(), TrueIfSigned ? 1 : 0);
2210 if (!Cmp.isEquality() || !
C.isZero() || !
Or->hasOneUse())
2241 if (
X ==
Mul->getOperand(1) && !Cmp.isSigned()) {
2243 bool IsSqr =
C == R * R;
2246 if (Cmp.isEquality() &&
2247 (
Mul->hasNoUnsignedWrap() || (
Mul->hasNoSignedWrap() &&
C.isZero()))) {
2255 return new ICmpInst(Pred,
X, ConstantInt::get(MulTy, R));
2260 if (
Mul->hasNoUnsignedWrap()) {
2263 return new ICmpInst(Pred,
X, ConstantInt::get(MulTy, R));
2277 return new ICmpInst(Cmp.getStrictPredicate(),
X,
2278 ConstantInt::get(MulTy, R));
2301 if (Cmp.isEquality()) {
2303 if (
Mul->hasNoSignedWrap() &&
C.srem(*MulC).isZero()) {
2304 Constant *NewC = ConstantInt::get(MulTy,
C.sdiv(*MulC));
2312 if (
C.urem(*MulC).isZero()) {
2315 if ((*MulC & 1).isOne() ||
Mul->hasNoUnsignedWrap()) {
2316 Constant *NewC = ConstantInt::get(MulTy,
C.udiv(*MulC));
2329 if (
C.isMinSignedValue() && MulC->
isAllOnes())
2335 NewC = ConstantInt::get(
2339 "Unexpected predicate");
2340 NewC = ConstantInt::get(
2345 NewC = ConstantInt::get(
2349 "Unexpected predicate");
2350 NewC = ConstantInt::get(
2355 return NewC ?
new ICmpInst(Pred,
X, NewC) :
nullptr;
2367 unsigned TypeBits =
C.getBitWidth();
2369 if (Cmp.isUnsigned()) {
2389 return new ICmpInst(Pred,
Y, ConstantInt::get(ShiftType, CLog2));
2390 }
else if (Cmp.isSigned() && C2->
isOne()) {
2391 Constant *BitWidthMinusOne = ConstantInt::get(ShiftType, TypeBits - 1);
2412 const APInt *ShiftVal;
2442 const APInt *ShiftAmt;
2448 unsigned TypeBits =
C.getBitWidth();
2449 if (ShiftAmt->
uge(TypeBits))
2461 APInt ShiftedC =
C.ashr(*ShiftAmt);
2462 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2465 C.ashr(*ShiftAmt).shl(*ShiftAmt) ==
C) {
2466 APInt ShiftedC =
C.ashr(*ShiftAmt);
2467 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2474 assert(!
C.isMinSignedValue() &&
"Unexpected icmp slt");
2475 APInt ShiftedC = (
C - 1).ashr(*ShiftAmt) + 1;
2476 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2486 APInt ShiftedC =
C.lshr(*ShiftAmt);
2487 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2490 C.lshr(*ShiftAmt).shl(*ShiftAmt) ==
C) {
2491 APInt ShiftedC =
C.lshr(*ShiftAmt);
2492 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2499 assert(
C.ugt(0) &&
"ult 0 should have been eliminated");
2500 APInt ShiftedC = (
C - 1).lshr(*ShiftAmt) + 1;
2501 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2505 if (Cmp.isEquality() && Shl->
hasOneUse()) {
2511 Constant *LShrC = ConstantInt::get(ShType,
C.lshr(*ShiftAmt));
2516 bool TrueIfSigned =
false;
2528 if (Cmp.isUnsigned() && Shl->
hasOneUse()) {
2530 if ((
C + 1).isPowerOf2() &&
2538 if (
C.isPowerOf2() &&
2568 Pred, ConstantInt::get(ShType->
getContext(),
C))) {
2569 CmpPred = FlippedStrictness->first;
2577 ConstantInt::get(TruncTy, RHSC.
ashr(*ShiftAmt).
trunc(TypeBits - Amt));
2579 Builder.CreateTrunc(
X, TruncTy,
"",
false,
2596 if (Cmp.isEquality() && Shr->
isExact() &&
C.isZero())
2597 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
2599 bool IsAShr = Shr->
getOpcode() == Instruction::AShr;
2600 const APInt *ShiftValC;
2602 if (Cmp.isEquality())
2620 assert(ShiftValC->
uge(
C) &&
"Expected simplify of compare");
2621 assert((IsUGT || !
C.isZero()) &&
"Expected X u< 0 to simplify");
2623 unsigned CmpLZ = IsUGT ?
C.countl_zero() : (
C - 1).
countl_zero();
2631 const APInt *ShiftAmtC;
2637 unsigned TypeBits =
C.getBitWidth();
2639 if (ShAmtVal >= TypeBits || ShAmtVal == 0)
2642 bool IsExact = Shr->
isExact();
2650 (
C - 1).isPowerOf2() &&
C.countLeadingZeros() > ShAmtVal) {
2656 APInt ShiftedC = (
C - 1).shl(ShAmtVal) + 1;
2657 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2663 APInt ShiftedC =
C.shl(ShAmtVal);
2664 if (ShiftedC.
ashr(ShAmtVal) ==
C)
2665 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2669 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2670 if (!
C.isMaxSignedValue() && !(
C + 1).shl(ShAmtVal).isMinSignedValue() &&
2671 (ShiftedC + 1).ashr(ShAmtVal) == (
C + 1))
2672 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2678 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2679 if ((ShiftedC + 1).ashr(ShAmtVal) == (
C + 1) ||
2680 (
C + 1).shl(ShAmtVal).isMinSignedValue())
2681 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2688 if (
C.getBitWidth() > 2 &&
C.getNumSignBits() <= ShAmtVal) {
2698 }
else if (!IsAShr) {
2702 APInt ShiftedC =
C.shl(ShAmtVal);
2703 if (ShiftedC.
lshr(ShAmtVal) ==
C)
2704 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2708 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2709 if ((ShiftedC + 1).lshr(ShAmtVal) == (
C + 1))
2710 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2714 if (!Cmp.isEquality())
2722 assert(((IsAShr &&
C.shl(ShAmtVal).ashr(ShAmtVal) ==
C) ||
2723 (!IsAShr &&
C.shl(ShAmtVal).lshr(ShAmtVal) ==
C)) &&
2724 "Expected icmp+shr simplify did not occur.");
2729 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy,
C << ShAmtVal));
2735 Constant *Mask = ConstantInt::get(ShrTy, Val);
2737 return new ICmpInst(Pred,
And, ConstantInt::get(ShrTy,
C << ShAmtVal));
2754 const APInt *DivisorC;
2763 "ult X, 0 should have been simplified already.");
2768 if (!NormalizedC.
uge(DivisorC->
abs() - 1))
2791 const APInt *DivisorC;
2800 !
C.isStrictlyPositive()))
2806 Constant *MaskC = ConstantInt::get(Ty, SignMask | (*DivisorC - 1));
2810 return new ICmpInst(Pred,
And, ConstantInt::get(Ty,
C));
2837 assert(*C2 != 0 &&
"udiv 0, X should have been simplified already.");
2842 "icmp ugt X, UINT_MAX should have been simplified already.");
2844 ConstantInt::get(Ty, C2->
udiv(
C + 1)));
2849 assert(
C != 0 &&
"icmp ult X, 0 should have been simplified already.");
2851 ConstantInt::get(Ty, C2->
udiv(
C)));
2865 bool DivIsSigned = Div->
getOpcode() == Instruction::SDiv;
2875 if (Cmp.isEquality() && Div->
hasOneUse() &&
C.isSignBitSet() &&
2876 (!DivIsSigned ||
C.isMinSignedValue())) {
2877 Value *XBig =
Builder.CreateICmp(Pred,
X, ConstantInt::get(Ty,
C));
2878 Value *YOne =
Builder.CreateICmp(Pred,
Y, ConstantInt::get(Ty, 1));
2904 if (!Cmp.isEquality() && DivIsSigned != Cmp.isSigned()) {
2908 DivIsSigned =
false;
2927 bool ProdOV = (DivIsSigned ? Prod.
sdiv(*C2) : Prod.
udiv(*C2)) !=
C;
2940 int LoOverflow = 0, HiOverflow = 0;
2941 APInt LoBound, HiBound;
2946 HiOverflow = LoOverflow = ProdOV;
2955 LoBound = -(RangeSize - 1);
2956 HiBound = RangeSize;
2957 }
else if (
C.isStrictlyPositive()) {
2959 HiOverflow = LoOverflow = ProdOV;
2965 LoOverflow = HiOverflow = ProdOV ? -1 : 0;
2967 APInt DivNeg = -RangeSize;
2968 LoOverflow =
addWithOverflow(LoBound, HiBound, DivNeg,
true) ? -1 : 0;
2976 LoBound = RangeSize + 1;
2977 HiBound = -RangeSize;
2978 if (HiBound == *C2) {
2982 }
else if (
C.isStrictlyPositive()) {
2985 HiOverflow = LoOverflow = ProdOV ? -1 : 0;
2991 LoOverflow = HiOverflow = ProdOV;
3004 if (LoOverflow && HiOverflow)
3008 X, ConstantInt::get(Ty, LoBound));
3011 X, ConstantInt::get(Ty, HiBound));
3015 if (LoOverflow && HiOverflow)
3019 X, ConstantInt::get(Ty, LoBound));
3022 X, ConstantInt::get(Ty, HiBound));
3027 if (LoOverflow == +1)
3029 if (LoOverflow == -1)
3031 return new ICmpInst(Pred,
X, ConstantInt::get(Ty, LoBound));
3034 if (HiOverflow == +1)
3036 if (HiOverflow == -1)
3078 bool HasNSW =
Sub->hasNoSignedWrap();
3079 bool HasNUW =
Sub->hasNoUnsignedWrap();
3081 ((Cmp.isUnsigned() && HasNUW) || (Cmp.isSigned() && HasNSW)) &&
3083 return new ICmpInst(SwappedPred,
Y, ConstantInt::get(Ty, SubResult));
3091 if (Cmp.isEquality() &&
C.isZero() &&
3092 none_of((
Sub->users()), [](
const User *U) { return isa<PHINode>(U); }))
3100 if (!
Sub->hasOneUse())
3103 if (
Sub->hasNoSignedWrap()) {
3127 (*C2 & (
C - 1)) == (
C - 1))
3140 return new ICmpInst(SwappedPred,
Add, ConstantInt::get(Ty, ~
C));
3146 auto FoldConstant = [&](
bool Val) {
3147 Constant *Res = Val ? Builder.getTrue() : Builder.getFalse();
3154 switch (
Table.to_ulong()) {
3156 return FoldConstant(
false);
3158 return HasOneUse ? Builder.CreateNot(Builder.CreateOr(Op0, Op1)) :
nullptr;
3160 return HasOneUse ? Builder.CreateAnd(Builder.CreateNot(Op0), Op1) :
nullptr;
3162 return Builder.CreateNot(Op0);
3164 return HasOneUse ? Builder.CreateAnd(Op0, Builder.CreateNot(Op1)) :
nullptr;
3166 return Builder.CreateNot(Op1);
3168 return Builder.CreateXor(Op0, Op1);
3170 return HasOneUse ? Builder.CreateNot(Builder.CreateAnd(Op0, Op1)) :
nullptr;
3172 return Builder.CreateAnd(Op0, Op1);
3174 return HasOneUse ? Builder.CreateNot(Builder.CreateXor(Op0, Op1)) :
nullptr;
3178 return HasOneUse ? Builder.CreateOr(Builder.CreateNot(Op0), Op1) :
nullptr;
3182 return HasOneUse ? Builder.CreateOr(Op0, Builder.CreateNot(Op1)) :
nullptr;
3184 return Builder.CreateOr(Op0, Op1);
3186 return FoldConstant(
true);
3201 Cmp.getType() !=
A->getType() || Cmp.getType() !=
B->getType())
3204 std::bitset<4>
Table;
3205 auto ComputeTable = [&](
bool First,
bool Second) -> std::optional<bool> {
3209 auto *Val = Res->getType()->isVectorTy() ? Res->getSplatValue() : Res;
3213 return std::nullopt;
3216 for (
unsigned I = 0;
I < 4; ++
I) {
3217 bool First = (
I >> 1) & 1;
3218 bool Second =
I & 1;
3219 if (
auto Res = ComputeTable(
First, Second))
3241 const APInt *ShAmtC;
3249 return new ICmpInst(Pred,
A, ConstantInt::get(
A->getType(),
C));
3261 if (
Add->hasNoUnsignedWrap() &&
3264 APInt NewC =
C.usub_ov(*C2, Overflow);
3268 return new ICmpInst(Pred,
X, ConstantInt::get(Ty, NewC));
3273 if (
Add->hasNoSignedWrap() &&
3276 APInt NewC =
C.ssub_ov(*C2, Overflow);
3280 return new ICmpInst(ChosenPred,
X, ConstantInt::get(Ty, NewC));
3284 C.isNonNegative() && (
C - *C2).isNonNegative() &&
3287 .isAllNonNegative())
3289 ConstantInt::get(Ty,
C - *C2));
3294 if (Cmp.isSigned()) {
3295 if (
Lower.isSignMask())
3297 if (
Upper.isSignMask())
3300 if (
Lower.isMinValue())
3302 if (
Upper.isMinValue())
3335 if (!
Add->hasOneUse())
3350 ConstantInt::get(Ty,
C * 2));
3364 Builder.CreateAdd(
X, ConstantInt::get(Ty, *C2 -
C - 1)),
3365 ConstantInt::get(Ty, ~
C));
3370 Type *NewCmpTy = V->getType();
3372 if (shouldChangeType(Ty, NewCmpTy)) {
3383 :
Builder.CreateAdd(V, ConstantInt::get(NewCmpTy, EquivOffset)),
3384 ConstantInt::get(NewCmpTy, EquivInt));
3406 Value *EqualVal =
SI->getTrueValue();
3407 Value *UnequalVal =
SI->getFalseValue();
3430 auto FlippedStrictness =
3432 if (!FlippedStrictness)
3435 "basic correctness failure");
3436 RHS2 = FlippedStrictness->second;
3448 assert(
C &&
"Cmp RHS should be a constant int!");
3454 Value *OrigLHS, *OrigRHS;
3455 ConstantInt *C1LessThan, *C2Equal, *C3GreaterThan;
3456 if (Cmp.hasOneUse() &&
3459 assert(C1LessThan && C2Equal && C3GreaterThan);
3462 C1LessThan->
getValue(),
C->getValue(), Cmp.getPredicate());
3464 Cmp.getPredicate());
3466 C3GreaterThan->
getValue(),
C->getValue(), Cmp.getPredicate());
3477 if (TrueWhenLessThan)
3483 if (TrueWhenGreaterThan)
3498 Value *Op1 = Cmp.getOperand(1);
3499 Value *BCSrcOp = Bitcast->getOperand(0);
3500 Type *SrcType = Bitcast->getSrcTy();
3501 Type *DstType = Bitcast->getType();
3505 if (SrcType->isVectorTy() == DstType->isVectorTy() &&
3506 SrcType->getScalarSizeInBits() == DstType->getScalarSizeInBits()) {
3521 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(), 1));
3548 Type *XType =
X->getType();
3551 if (!(XType->
isPPC_FP128Ty() || SrcType->isPPC_FP128Ty())) {
3566 Type *FPType = SrcType->getScalarType();
3567 if (!Cmp.getParent()->getParent()->hasFnAttribute(
3568 Attribute::NoImplicitFloat) &&
3569 Cmp.isEquality() && FPType->isIEEELikeFPTy()) {
3575 Builder.createIsFPClass(BCSrcOp, Mask));
3598 if (!
match(Cmp.getOperand(1),
m_APInt(
C)) || !DstType->isIntegerTy() ||
3599 !SrcType->isIntOrIntVectorTy())
3609 if (Cmp.isEquality() &&
C->isAllOnes() && Bitcast->hasOneUse()) {
3610 if (
Value *NotBCSrcOp =
3612 Value *Cast =
Builder.CreateBitCast(NotBCSrcOp, DstType);
3621 if (Cmp.isEquality() &&
C->isZero() && Bitcast->hasOneUse() &&
3624 Type *NewType =
Builder.getIntNTy(VecTy->getPrimitiveSizeInBits());
3644 if (
C->isSplat(EltTy->getBitWidth())) {
3650 Value *Extract =
Builder.CreateExtractElement(Vec, Mask[0]);
3651 Value *NewC = ConstantInt::get(EltTy,
C->trunc(EltTy->getBitWidth()));
3652 return new ICmpInst(Pred, Extract, NewC);
3690 if (
match(Cmp.getOperand(0),
3696 bool ValidPred =
true;
3714 X->getType()->getScalarType()->getFltSemantics();
3717 if (!Exp.isNegative() && Exp.sle(MaxExp + 1) &&
3719 int ExpVal =
static_cast<int>(Exp.getSExtValue());
3724 ConstantFP::get(
X->getType(), CmpConst));
3733 Value *Cmp0 = Cmp.getOperand(0);
3735 if (
C->isZero() && Cmp.isEquality() && Cmp0->
hasOneUse() &&
3742 return new ICmpInst(Cmp.getPredicate(),
X,
Y);
3757 if (!Cmp.isEquality())
3766 case Instruction::SRem:
3777 case Instruction::Add: {
3784 }
else if (
C.isZero()) {
3787 if (
Value *NegVal = dyn_castNegVal(BOp1))
3788 return new ICmpInst(Pred, BOp0, NegVal);
3789 if (
Value *NegVal = dyn_castNegVal(BOp0))
3790 return new ICmpInst(Pred, NegVal, BOp1);
3799 return new ICmpInst(Pred, BOp0, Neg);
3804 case Instruction::Xor:
3809 }
else if (
C.isZero()) {
3811 return new ICmpInst(Pred, BOp0, BOp1);
3814 case Instruction::Or: {
3835 Cond->getType() == Cmp.getType()) {
3873 case Instruction::UDiv:
3874 case Instruction::SDiv:
3884 return new ICmpInst(Pred, BOp0, BOp1);
3887 Instruction::Mul, BO->
getOpcode() == Instruction::SDiv, BOp1,
3888 Cmp.getOperand(1), BO);
3892 return new ICmpInst(Pred, YC, BOp0);
3896 if (BO->
getOpcode() == Instruction::UDiv &&
C.isZero()) {
3899 return new ICmpInst(NewPred, BOp1, BOp0);
3913 "Non-ctpop intrin in ctpop fold");
3948 Type *Ty =
II->getType();
3952 switch (
II->getIntrinsicID()) {
3953 case Intrinsic::abs:
3956 if (
C.isZero() ||
C.isMinSignedValue())
3957 return new ICmpInst(Pred,
II->getArgOperand(0), ConstantInt::get(Ty,
C));
3960 case Intrinsic::bswap:
3962 return new ICmpInst(Pred,
II->getArgOperand(0),
3963 ConstantInt::get(Ty,
C.byteSwap()));
3965 case Intrinsic::bitreverse:
3967 return new ICmpInst(Pred,
II->getArgOperand(0),
3968 ConstantInt::get(Ty,
C.reverseBits()));
3970 case Intrinsic::ctlz:
3971 case Intrinsic::cttz: {
3974 return new ICmpInst(Pred,
II->getArgOperand(0),
3980 unsigned Num =
C.getLimitedValue(
BitWidth);
3982 bool IsTrailing =
II->getIntrinsicID() == Intrinsic::cttz;
3985 APInt Mask2 = IsTrailing
3989 ConstantInt::get(Ty, Mask2));
3994 case Intrinsic::ctpop: {
3997 bool IsZero =
C.isZero();
3999 return new ICmpInst(Pred,
II->getArgOperand(0),
4006 case Intrinsic::fshl:
4007 case Intrinsic::fshr:
4008 if (
II->getArgOperand(0) ==
II->getArgOperand(1)) {
4009 const APInt *RotAmtC;
4013 return new ICmpInst(Pred,
II->getArgOperand(0),
4014 II->getIntrinsicID() == Intrinsic::fshl
4015 ? ConstantInt::get(Ty,
C.rotr(*RotAmtC))
4016 : ConstantInt::get(Ty,
C.rotl(*RotAmtC)));
4020 case Intrinsic::umax:
4021 case Intrinsic::uadd_sat: {
4024 if (
C.isZero() &&
II->hasOneUse()) {
4031 case Intrinsic::ssub_sat:
4036 if (
C.isZero() &&
II->getType()->getScalarSizeInBits() > 1)
4037 return new ICmpInst(Pred,
II->getArgOperand(0),
II->getArgOperand(1));
4039 case Intrinsic::usub_sat: {
4044 return new ICmpInst(NewPred,
II->getArgOperand(0),
II->getArgOperand(1));
4059 assert(Cmp.isEquality());
4062 Value *Op0 = Cmp.getOperand(0);
4063 Value *Op1 = Cmp.getOperand(1);
4066 if (!IIOp0 || !IIOp1 || IIOp0->getIntrinsicID() != IIOp1->getIntrinsicID())
4069 switch (IIOp0->getIntrinsicID()) {
4070 case Intrinsic::bswap:
4071 case Intrinsic::bitreverse:
4074 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
4075 case Intrinsic::fshl:
4076 case Intrinsic::fshr: {
4079 if (IIOp0->getOperand(0) != IIOp0->getOperand(1))
4081 if (IIOp1->getOperand(0) != IIOp1->getOperand(1))
4083 if (IIOp0->getOperand(2) == IIOp1->getOperand(2))
4084 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
4090 const unsigned BW = IIOp0->getType()->getScalarSizeInBits();
4091 unsigned OneUses = IIOp0->hasOneUse() + IIOp1->hasOneUse();
4100 Builder.CreateSub(IIOp0->getOperand(2), IIOp1->getOperand(2));
4101 Value *CombinedRotate = Builder.CreateIntrinsic(
4102 Op0->
getType(), IIOp0->getIntrinsicID(),
4103 {IIOp0->getOperand(0), IIOp0->getOperand(0), SubAmt});
4104 return new ICmpInst(Pred, IIOp1->getOperand(0), CombinedRotate);
4123 switch (
II->getIntrinsicID()) {
4126 case Intrinsic::fshl:
4127 case Intrinsic::fshr:
4128 if (Cmp.isEquality() &&
II->getArgOperand(0) ==
II->getArgOperand(1)) {
4130 if (
C.isZero() ||
C.isAllOnes())
4131 return new ICmpInst(Pred,
II->getArgOperand(0), Cmp.getOperand(1));
4145 case Instruction::Xor:
4149 case Instruction::And:
4153 case Instruction::Or:
4157 case Instruction::Mul:
4161 case Instruction::Shl:
4165 case Instruction::LShr:
4166 case Instruction::AShr:
4170 case Instruction::SRem:
4174 case Instruction::UDiv:
4178 case Instruction::SDiv:
4182 case Instruction::Sub:
4186 case Instruction::Add:
4210 if (!
II->hasOneUse())
4226 Value *Op0 =
II->getOperand(0);
4227 Value *Op1 =
II->getOperand(1);
4236 switch (
II->getIntrinsicID()) {
4239 "This function only works with usub_sat and uadd_sat for now!");
4240 case Intrinsic::uadd_sat:
4243 case Intrinsic::usub_sat:
4253 II->getBinaryOp(), *COp1,
II->getNoWrapKind());
4260 if (
II->getBinaryOp() == Instruction::Add)
4266 SatValCheck ? Instruction::BinaryOps::Or : Instruction::BinaryOps::And;
4268 std::optional<ConstantRange> Combination;
4269 if (CombiningOp == Instruction::BinaryOps::Or)
4281 Combination->getEquivalentICmp(EquivPred, EquivInt, EquivOffset);
4285 Builder.CreateAdd(Op0, ConstantInt::get(Op1->
getType(), EquivOffset)),
4286 ConstantInt::get(Op1->
getType(), EquivInt));
4293 std::optional<ICmpInst::Predicate> NewPredicate = std::nullopt;
4298 NewPredicate = Pred;
4302 else if (
C.isAllOnes())
4310 else if (
C.isZero())
4327 if (!
C.isZero() && !
C.isAllOnes())
4338 if (
I->getIntrinsicID() == Intrinsic::scmp)
4352 switch (
II->getIntrinsicID()) {
4355 case Intrinsic::uadd_sat:
4356 case Intrinsic::usub_sat:
4361 case Intrinsic::ctpop: {
4366 case Intrinsic::scmp:
4367 case Intrinsic::ucmp:
4373 if (Cmp.isEquality())
4376 Type *Ty =
II->getType();
4378 switch (
II->getIntrinsicID()) {
4379 case Intrinsic::ctpop: {
4391 case Intrinsic::ctlz: {
4394 unsigned Num =
C.getLimitedValue();
4397 II->getArgOperand(0), ConstantInt::get(Ty, Limit));
4402 unsigned Num =
C.getLimitedValue();
4405 II->getArgOperand(0), ConstantInt::get(Ty, Limit));
4409 case Intrinsic::cttz: {
4411 if (!
II->hasOneUse())
4418 Builder.CreateAnd(
II->getArgOperand(0), Mask),
4426 Builder.CreateAnd(
II->getArgOperand(0), Mask),
4431 case Intrinsic::ssub_sat:
4438 return new ICmpInst(Pred,
II->getArgOperand(0),
II->getArgOperand(1));
4442 II->getArgOperand(1));
4446 II->getArgOperand(1));
4449 case Intrinsic::abs: {
4450 if (!
II->hasOneUse())
4459 Builder.CreateAdd(
X, ConstantInt::get(Ty,
C)),
4460 ConstantInt::get(Ty, 2 *
C));
4467 Builder.CreateAdd(
X, ConstantInt::get(Ty,
C - 1)),
4468 ConstantInt::get(Ty, 2 * (
C - 1)));
4481 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
4488 case Instruction::IntToPtr:
4493 APInt NullPtrValue =
4501 case Instruction::Load:
4518 auto SimplifyOp = [&](
Value *
Op,
bool SelectCondIsTrue) ->
Value * {
4522 SI->getCondition(), Pred,
Op, RHS,
DL, SelectCondIsTrue))
4523 return ConstantInt::get(
I.getType(), *Impl);
4528 Value *Op1 = SimplifyOp(
SI->getOperand(1),
true);
4532 Value *Op2 = SimplifyOp(
SI->getOperand(2),
false);
4536 auto Simplifies = [&](
Value *
Op,
unsigned Idx) {
4551 bool Transform =
false;
4554 else if (Simplifies(Op1, 1) || Simplifies(Op2, 2)) {
4556 if (
SI->hasOneUse())
4559 else if (CI && !CI->
isZero())
4567 Op1 =
Builder.CreateICmp(Pred,
SI->getOperand(1), RHS,
I.getName());
4569 Op2 =
Builder.CreateICmp(Pred,
SI->getOperand(2), RHS,
I.getName());
4580 const APInt *C1, *C2, *
P;
4587 if (C1SatisfiesCond && !C2SatisfiesCond) {
4591 Value *Cmp2 =
Builder.CreateICmp(Pred, RHS,
SI->getFalseValue());
4593 return BinaryOperator::CreateOr(Cmp1, Cmp2);
4594 return BinaryOperator::CreateAnd(Cmp1, Cmp2);
4604 unsigned Depth = 0) {
4607 if (V->getType()->getScalarSizeInBits() == 1)
4615 switch (
I->getOpcode()) {
4616 case Instruction::ZExt:
4619 case Instruction::SExt:
4623 case Instruction::And:
4624 case Instruction::Or:
4631 case Instruction::Xor:
4641 case Instruction::Select:
4645 case Instruction::Shl:
4648 case Instruction::LShr:
4651 case Instruction::AShr:
4655 case Instruction::Add:
4661 case Instruction::Sub:
4667 case Instruction::Call: {
4669 switch (
II->getIntrinsicID()) {
4672 case Intrinsic::umax:
4673 case Intrinsic::smax:
4674 case Intrinsic::umin:
4675 case Intrinsic::smin:
4680 case Intrinsic::bitreverse:
4770 auto IsLowBitMask = [&]() {
4788 auto Check = [&]() {
4806 auto Check = [&]() {
4825 if (!IsLowBitMask())
4844 const APInt *C0, *C1;
4861 const APInt &MaskedBits = *C0;
4862 assert(MaskedBits != 0 &&
"shift by zero should be folded away already.");
4883 auto *XType =
X->getType();
4884 const unsigned XBitWidth = XType->getScalarSizeInBits();
4886 assert(
BitWidth.ugt(MaskedBits) &&
"shifts should leave some bits untouched");
4899 Value *T0 = Builder.CreateAdd(
X, ConstantInt::get(XType, AddCst));
4901 Value *
T1 = Builder.CreateICmp(DstPred, T0, ConstantInt::get(XType, ICmpCst));
4917 !
I.getOperand(0)->hasOneUse())
4942 assert(NarrowestTy ==
I.getOperand(0)->getType() &&
4943 "We did not look past any shifts while matching XShift though.");
4944 bool HadTrunc = WidestTy !=
I.getOperand(0)->getType();
4951 auto XShiftOpcode = XShift->
getOpcode();
4952 if (XShiftOpcode == YShift->
getOpcode())
4955 Value *
X, *XShAmt, *
Y, *YShAmt;
4964 if (!
match(
I.getOperand(0),
4990 unsigned MaximalPossibleTotalShiftAmount =
4993 APInt MaximalRepresentableShiftAmount =
4995 if (MaximalRepresentableShiftAmount.
ult(MaximalPossibleTotalShiftAmount))
5004 if (NewShAmt->getType() != WidestTy) {
5014 if (!
match(NewShAmt,
5016 APInt(WidestBitWidth, WidestBitWidth))))
5021 auto CanFold = [NewShAmt, WidestBitWidth, NarrowestShift, SQ,
5027 ? NewShAmt->getSplatValue()
5030 if (NewShAmtSplat &&
5038 unsigned MinLeadZero =
Known.countMinLeadingZeros();
5040 unsigned MaxActiveBits =
Known.getBitWidth() - MinLeadZero;
5041 if (MaxActiveBits <= 1)
5049 unsigned MinLeadZero =
Known.countMinLeadingZeros();
5051 unsigned MaxActiveBits =
Known.getBitWidth() - MinLeadZero;
5052 if (MaxActiveBits <= 1)
5055 if (NewShAmtSplat) {
5058 if (AdjNewShAmt.
ule(MinLeadZero))
5069 X = Builder.CreateZExt(
X, WidestTy);
5070 Y = Builder.CreateZExt(
Y, WidestTy);
5072 Value *T0 = XShiftOpcode == Instruction::BinaryOps::LShr
5073 ? Builder.CreateLShr(
X, NewShAmt)
5074 : Builder.CreateShl(
X, NewShAmt);
5075 Value *
T1 = Builder.CreateAnd(T0,
Y);
5076 return Builder.CreateICmp(
I.getPredicate(),
T1,
5094 if (!
I.isEquality() &&
5104 NeedNegation =
false;
5107 NeedNegation =
true;
5113 if (
I.isEquality() &&
5128 bool MulHadOtherUses =
Mul && !
Mul->hasOneUse();
5129 if (MulHadOtherUses)
5133 Div->
getOpcode() == Instruction::UDiv ? Intrinsic::umul_with_overflow
5134 : Intrinsic::smul_with_overflow,
5135 X->getType(), {X, Y},
nullptr,
"mul");
5140 if (MulHadOtherUses)
5145 Res =
Builder.CreateNot(Res,
"mul.not.ov");
5149 if (MulHadOtherUses)
5175 Type *Ty =
X->getType();
5179 Value *
And = Builder.CreateAnd(
X, MaxSignedVal);
5189 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5251 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5286 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5302 return new ICmpInst(PredOut, Op0, Op1);
5322 return new ICmpInst(NewPred, Op0, Const);
5334 if (!
C.isPowerOf2())
5347 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5362 Value *Dividend, *Divisor;
5363 if (
I.isEquality() &&
5368 return new ICmpInst(NewPred, Dividend, Divisor);
5427 return new ICmpInst(NewPred, Op1, Zero);
5436 return new ICmpInst(NewPred, Op0, Zero);
5440 bool NoOp0WrapProblem =
false, NoOp1WrapProblem =
false;
5441 bool Op0HasNUW =
false, Op1HasNUW =
false;
5442 bool Op0HasNSW =
false, Op1HasNSW =
false;
5446 bool &HasNSW,
bool &HasNUW) ->
bool {
5453 }
else if (BO.
getOpcode() == Instruction::Or) {
5463 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr;
5467 NoOp0WrapProblem = hasNoWrapProblem(*BO0, Pred, Op0HasNSW, Op0HasNUW);
5471 NoOp1WrapProblem = hasNoWrapProblem(*BO1, Pred, Op1HasNSW, Op1HasNUW);
5476 if ((
A == Op1 ||
B == Op1) && NoOp0WrapProblem)
5482 if ((
C == Op0 ||
D == Op0) && NoOp1WrapProblem)
5487 if (
A &&
C && (
A ==
C ||
A ==
D ||
B ==
C ||
B ==
D) && NoOp0WrapProblem &&
5495 }
else if (
A ==
D) {
5499 }
else if (
B ==
C) {
5516 bool IsNegative) ->
bool {
5517 const APInt *OffsetC;
5529 if (!
C.isStrictlyPositive())
5556 if (
A && NoOp0WrapProblem && IsAddOrSignedPred &&
5557 ShareCommonDivisor(
A, Op1,
B, IsNegative))
5567 if (
C && NoOp1WrapProblem &&
5568 ShareCommonDivisor(Op0,
C,
D,
5581 if (
A &&
C && NoOp0WrapProblem && NoOp1WrapProblem &&
5583 const APInt *AP1, *AP2;
5591 if (AP1Abs.
uge(AP2Abs)) {
5592 APInt Diff = *AP1 - *AP2;
5595 A, C3,
"", Op0HasNUW && Diff.
ule(*AP1), Op0HasNSW);
5598 APInt Diff = *AP2 - *AP1;
5601 C, C3,
"", Op1HasNUW && Diff.
ule(*AP2), Op1HasNSW);
5620 if (BO0 && BO0->
getOpcode() == Instruction::Sub) {
5624 if (BO1 && BO1->
getOpcode() == Instruction::Sub) {
5630 if (
A == Op1 && NoOp0WrapProblem)
5633 if (
C == Op0 && NoOp1WrapProblem)
5653 if (
B &&
D &&
B ==
D && NoOp0WrapProblem && NoOp1WrapProblem)
5657 if (
A &&
C &&
A ==
C && NoOp0WrapProblem && NoOp1WrapProblem)
5665 if (RHSC->isNotMinSignedValue())
5666 return new ICmpInst(
I.getSwappedPredicate(),
X,
5684 if (Op0HasNSW && Op1HasNSW) {
5691 SQ.getWithInstruction(&
I));
5696 SQ.getWithInstruction(&
I));
5697 if (GreaterThan &&
match(GreaterThan,
m_One()))
5704 if (((Op0HasNSW && Op1HasNSW) || (Op0HasNUW && Op1HasNUW)) &&
5716 if (NonZero && BO0 && BO1 && Op0HasNSW && Op1HasNSW)
5723 if (NonZero && BO0 && BO1 && Op0HasNUW && Op1HasNUW)
5734 else if (BO1 && BO1->
getOpcode() == Instruction::SRem &&
5764 case Instruction::Add:
5765 case Instruction::Sub:
5766 case Instruction::Xor: {
5773 if (
C->isSignMask()) {
5779 if (BO0->
getOpcode() == Instruction::Xor &&
C->isMaxSignedValue()) {
5781 NewPred =
I.getSwappedPredicate(NewPred);
5787 case Instruction::Mul: {
5788 if (!
I.isEquality())
5796 if (
unsigned TZs =
C->countr_zero()) {
5802 return new ICmpInst(Pred, And1, And2);
5807 case Instruction::UDiv:
5808 case Instruction::LShr:
5813 case Instruction::SDiv:
5819 case Instruction::AShr:
5824 case Instruction::Shl: {
5825 bool NUW = Op0HasNUW && Op1HasNUW;
5826 bool NSW = Op0HasNSW && Op1HasNSW;
5829 if (!NSW &&
I.isSigned())
5893 auto IsCondKnownTrue = [](
Value *Val) -> std::optional<bool> {
5895 return std::nullopt;
5900 return std::nullopt;
5906 Pred = Pred.dropSameSign();
5909 if (!CmpXZ.has_value() && !CmpYZ.has_value())
5911 if (!CmpXZ.has_value()) {
5917 if (CmpYZ.has_value())
5941 if (!MinMaxCmpXZ.has_value()) {
5949 if (!MinMaxCmpXZ.has_value())
5965 return FoldIntoCmpYZ();
5992 return FoldIntoCmpYZ();
6001 return FoldIntoCmpYZ();
6033 const APInt *
Lo =
nullptr, *
Hi =
nullptr;
6056 I,
Builder.CreateICmp(Pred,
X, ConstantInt::get(
X->getType(),
C)));
6062 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6066 if (
I.isEquality()) {
6101 Type *Ty =
A->getType();
6102 Value *CtPop = Builder.CreateUnaryIntrinsic(Intrinsic::ctpop,
A);
6104 ConstantInt::get(Ty, 2))
6106 ConstantInt::get(Ty, 1));
6113using OffsetOp = std::pair<Instruction::BinaryOps, Value *>;
6115 bool AllowRecursion) {
6121 case Instruction::Add:
6122 Offsets.emplace_back(Instruction::Sub, Inst->
getOperand(1));
6123 Offsets.emplace_back(Instruction::Sub, Inst->
getOperand(0));
6125 case Instruction::Sub:
6126 Offsets.emplace_back(Instruction::Add, Inst->
getOperand(1));
6128 case Instruction::Xor:
6129 Offsets.emplace_back(Instruction::Xor, Inst->
getOperand(1));
6130 Offsets.emplace_back(Instruction::Xor, Inst->
getOperand(0));
6132 case Instruction::Shl:
6134 Offsets.emplace_back(Instruction::AShr, Inst->
getOperand(1));
6136 Offsets.emplace_back(Instruction::LShr, Inst->
getOperand(1));
6138 case Instruction::Select:
6139 if (AllowRecursion) {
6186 assert(
I.isEquality() &&
"Expected an equality icmp");
6187 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6198 case Instruction::AShr: {
6199 const APInt *CV, *CRHS;
6201 CV->
ashr(*CRHS).
shl(*CRHS) == *CV) &&
6207 case Instruction::LShr: {
6208 const APInt *CV, *CRHS;
6210 CV->
lshr(*CRHS).
shl(*CRHS) == *CV) &&
6229 auto ApplyOffset = [&](
Value *V,
unsigned BinOpc,
6232 if (!Sel->hasOneUse())
6234 Value *TrueVal = ApplyOffsetImpl(Sel->getTrueValue(), BinOpc,
RHS);
6237 Value *FalseVal = ApplyOffsetImpl(Sel->getFalseValue(), BinOpc,
RHS);
6242 if (
Value *Simplified = ApplyOffsetImpl(V, BinOpc,
RHS))
6247 for (
auto [BinOp,
RHS] : OffsetOps) {
6248 auto BinOpc =
static_cast<unsigned>(BinOp);
6250 auto Op0Result = ApplyOffset(Op0, BinOpc,
RHS);
6251 if (!Op0Result.isValid())
6253 auto Op1Result = ApplyOffset(Op1, BinOpc,
RHS);
6254 if (!Op1Result.isValid())
6257 Value *NewLHS = Op0Result.materialize(Builder);
6258 Value *NewRHS = Op1Result.materialize(Builder);
6259 return new ICmpInst(
I.getPredicate(), NewLHS, NewRHS);
6266 if (!
I.isEquality())
6269 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6273 if (
A == Op1 ||
B == Op1) {
6274 Value *OtherVal =
A == Op1 ?
B :
A;
6302 Value *OtherVal =
A == Op0 ?
B :
A;
6309 Value *
X =
nullptr, *
Y =
nullptr, *Z =
nullptr;
6315 }
else if (
A ==
D) {
6319 }
else if (
B ==
C) {
6323 }
else if (
B ==
D) {
6333 const APInt *C0, *C1;
6335 (*C0 ^ *C1).isNegatedPowerOf2();
6341 int(Op0->
hasOneUse()) + int(Op1->hasOneUse()) +
6343 if (XorIsNegP2 || UseCnt >= 2) {
6346 Op1 =
Builder.CreateAnd(Op1, Z);
6366 (Op0->
hasOneUse() || Op1->hasOneUse())) {
6371 MaskC->
countr_one() ==
A->getType()->getScalarSizeInBits())
6377 const APInt *AP1, *AP2;
6386 if (ShAmt < TypeBits && ShAmt != 0) {
6391 return new ICmpInst(NewPred,
Xor, ConstantInt::get(
A->getType(), CmpVal));
6401 if (ShAmt < TypeBits && ShAmt != 0) {
6421 if (ShAmt < ASize) {
6444 A->getType()->getScalarSizeInBits() ==
BitWidth * 2 &&
6445 (
I.getOperand(0)->hasOneUse() ||
I.getOperand(1)->hasOneUse())) {
6450 Add, ConstantInt::get(
A->getType(),
C.shl(1)));
6477 Builder.CreateIntrinsic(Op0->
getType(), Intrinsic::fshl, {A, A, B}));
6492 std::optional<bool> IsZero = std::nullopt;
6534 Constant *
C = ConstantInt::get(Res->X->getType(), Res->C);
6538 unsigned SrcBits =
X->getType()->getScalarSizeInBits();
6540 if (
II->getIntrinsicID() == Intrinsic::cttz ||
6541 II->getIntrinsicID() == Intrinsic::ctlz) {
6542 unsigned MaxRet = SrcBits;
6568 bool IsSignedExt = CastOp0->getOpcode() == Instruction::SExt;
6569 bool IsSignedCmp = ICmp.
isSigned();
6577 if (IsZext0 != IsZext1) {
6582 if (ICmp.
isEquality() &&
X->getType()->isIntOrIntVectorTy(1) &&
6583 Y->getType()->isIntOrIntVectorTy(1))
6593 bool IsNonNeg0 = NonNegInst0 && NonNegInst0->hasNonNeg();
6594 bool IsNonNeg1 = NonNegInst1 && NonNegInst1->hasNonNeg();
6596 if ((IsZext0 && IsNonNeg0) || (IsZext1 && IsNonNeg1))
6603 Type *XTy =
X->getType(), *YTy =
Y->getType();
6610 IsSignedExt ? Instruction::SExt : Instruction::ZExt;
6612 X =
Builder.CreateCast(CastOpcode,
X, YTy);
6614 Y =
Builder.CreateCast(CastOpcode,
Y, XTy);
6626 if (IsSignedCmp && IsSignedExt)
6639 Type *SrcTy = CastOp0->getSrcTy();
6647 if (IsSignedExt && IsSignedCmp)
6678 Value *SimplifiedOp0 = simplifyIntToPtrRoundTripCast(ICmp.
getOperand(0));
6679 Value *SimplifiedOp1 = simplifyIntToPtrRoundTripCast(ICmp.
getOperand(1));
6680 if (SimplifiedOp0 || SimplifiedOp1)
6682 SimplifiedOp0 ? SimplifiedOp0 : ICmp.
getOperand(0),
6683 SimplifiedOp1 ? SimplifiedOp1 : ICmp.
getOperand(1));
6692 Value *Op0Src = CastOp0->getOperand(0);
6693 Type *SrcTy = CastOp0->getSrcTy();
6694 Type *DestTy = CastOp0->getDestTy();
6698 auto CompatibleSizes = [&](
Type *PtrTy,
Type *IntTy) {
6699 unsigned IntWidth = IntTy->getScalarType()->getIntegerBitWidth();
6700 unsigned IndexWidth =
DL.getAddressSizeInBits(PtrTy);
6701 unsigned PtrWidth =
DL.getPointerTypeSizeInBits(PtrTy);
6704 return IntWidth == IndexWidth && IndexWidth == PtrWidth;
6708 Value *NewOp1 =
nullptr;
6710 NewOp1 = PtrToIntOp1->getOperand(0);
6713 NewOp1 = PtrToAddrOp1->getOperand(0);
6720 if ((!HasPtrToInt || CompatibleSizes(SrcTy, DestTy)) &&
6726 if (CastOp0->getOpcode() == Instruction::IntToPtr &&
6727 CompatibleSizes(DestTy, SrcTy)) {
6728 Value *NewOp1 =
nullptr;
6730 Value *IntSrc = IntToPtrOp1->getOperand(0);
6732 NewOp1 = IntToPtrOp1->getOperand(0);
6752 case Instruction::Add:
6753 case Instruction::Sub:
6755 case Instruction::Mul:
6756 return !(
RHS->getType()->isIntOrIntVectorTy(1) && IsSigned) &&
6768 case Instruction::Add:
6773 case Instruction::Sub:
6778 case Instruction::Mul:
6787 bool IsSigned,
Value *LHS,
6798 Builder.SetInsertPoint(&OrigI);
6815 Result = Builder.CreateBinOp(BinaryOp,
LHS,
RHS);
6816 Result->takeName(&OrigI);
6820 Result = Builder.CreateBinOp(BinaryOp,
LHS,
RHS);
6821 Result->takeName(&OrigI);
6825 Inst->setHasNoSignedWrap();
6827 Inst->setHasNoUnsignedWrap();
6852 const APInt *OtherVal,
6860 unsigned Opcode = Instr->getOpcode();
6861 assert(Opcode == Instruction::Add || Opcode == Instruction::Mul);
6868 Type *TyA =
A->getType(), *TyB =
B->getType();
6870 WidthB = TyB->getPrimitiveSizeInBits();
6871 unsigned ResultWidth;
6873 if (WidthB > WidthA) {
6874 ResultWidth = WidthB;
6877 ResultWidth = WidthA;
6890 unsigned TruncWidth = TI->getType()->getPrimitiveSizeInBits();
6891 if (TruncWidth > ResultWidth)
6895 if (BO->getOpcode() != Instruction::And)
6898 const APInt &CVal = CI->getValue();
6914 switch (
I.getPredicate()) {
6921 if (MaxVal.
eq(*OtherVal))
6931 if (MaxVal.
eq(*OtherVal))
6944 Value *ResultA =
A, *ResultB =
B;
6945 if (WidthA < ResultWidth)
6946 ResultA = Builder.CreateZExt(
A, ResultType);
6947 if (WidthB < ResultWidth)
6948 ResultB = Builder.CreateZExt(
B, ResultType);
6951 Value *OverflowCheck;
6953 if (Opcode == Instruction::Add) {
6955 ArithResult = Builder.CreateAdd(ResultA, ResultB,
"add");
6959 Builder.CreateICmpUGE(ArithResult, ResultA,
"not.add.overflow");
6962 Builder.CreateICmpULT(ArithResult, ResultA,
"add.overflow");
6965 Value *
Call = Builder.CreateIntrinsic(Intrinsic::umul_with_overflow,
6966 ResultType, {ResultA, ResultB},
6968 ArithResult = Builder.CreateExtractValue(
Call, 0,
"umul.value");
6969 OverflowCheck = Builder.CreateExtractValue(
Call, 1,
"umul.overflow");
6971 OverflowCheck = Builder.CreateNot(OverflowCheck);
6982 if (TI->getType()->getPrimitiveSizeInBits() == ResultWidth)
6987 assert(BO->getOpcode() == Instruction::And);
6991 Value *ShortAnd = Builder.CreateAnd(ArithResult, ShortMask);
6992 Value *Zext = Builder.CreateZExt(ShortAnd, BO->
getType());
7018 switch (
I.getPredicate()) {
7049 assert(DI && UI &&
"Instruction not defined\n");
7061 if (Usr != UI && !
DT.dominates(DB, Usr->getParent()))
7076 if (!IC || (IC->getOperand(0) !=
SI && IC->getOperand(1) !=
SI))
7123 const unsigned SIOpd) {
7124 assert((SIOpd == 1 || SIOpd == 2) &&
"Invalid select operand!");
7126 BasicBlock *Succ =
SI->getParent()->getTerminator()->getSuccessor(1);
7140 SI->replaceUsesOutsideBlock(
SI->getOperand(SIOpd),
SI->getParent());
7150 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7155 unsigned BitWidth = Ty->isIntOrIntVectorTy()
7156 ? Ty->getScalarSizeInBits()
7157 :
DL.getPointerTypeSizeInBits(Ty->getScalarType());
7181 if (
I.hasSameSign() &&
I.isUnsigned()) {
7183 if (To.isNegative() || To.isNonNegative())
7188 To.makeNonNegative();
7190 PropagateSignBit(Op0Known, Op1Known);
7191 PropagateSignBit(Op1Known, Op0Known);
7226 if (!Cmp.hasOneUse())
7235 if (!isMinMaxCmp(
I)) {
7240 if (Op1Min == Op0Max)
7245 if (*CmpC == Op0Min + 1)
7247 ConstantInt::get(Op1->getType(), *CmpC - 1));
7257 if (Op1Max == Op0Min)
7262 if (*CmpC == Op0Max - 1)
7264 ConstantInt::get(Op1->getType(), *CmpC + 1));
7274 if (Op1Min == Op0Max)
7278 if (*CmpC == Op0Min + 1)
7280 ConstantInt::get(Op1->getType(), *CmpC - 1));
7285 if (Op1Max == Op0Min)
7289 if (*CmpC == Op0Max - 1)
7291 ConstantInt::get(Op1->getType(), *CmpC + 1));
7308 APInt Op0KnownZeroInverted = ~Op0Known.Zero;
7311 Value *LHS =
nullptr;
7314 *LHSC != Op0KnownZeroInverted)
7320 Type *XTy =
X->getType();
7322 APInt C2 = Op0KnownZeroInverted;
7323 APInt C2Pow2 = (C2 & ~(*C1 - 1)) + *C1;
7329 auto *CmpC = ConstantInt::get(XTy, Log2C2 - Log2C1);
7339 (Op0Known & Op1Known) == Op0Known)
7345 if (Op1Min == Op0Max)
7349 if (Op1Max == Op0Min)
7353 if (Op1Min == Op0Max)
7357 if (Op1Max == Op0Min)
7365 if ((
I.isSigned() || (
I.isUnsigned() && !
I.hasSameSign())) &&
7368 I.setPredicate(
I.getUnsignedPredicate());
7386 return BinaryOperator::CreateAnd(
Builder.CreateIsNull(
X),
Y);
7392 return BinaryOperator::CreateOr(
Builder.CreateIsNull(
X),
Y);
7403 bool IsSExt = ExtI->
getOpcode() == Instruction::SExt;
7405 auto CreateRangeCheck = [&] {
7420 }
else if (!IsSExt || HasOneUse) {
7425 return CreateRangeCheck();
7427 }
else if (IsSExt ?
C->isAllOnes() :
C->isOne()) {
7435 }
else if (!IsSExt || HasOneUse) {
7440 return CreateRangeCheck();
7454 Instruction::ICmp, Pred1,
X,
7473 Value *Op0 =
I.getOperand(0);
7474 Value *Op1 =
I.getOperand(1);
7480 if (!FlippedStrictness)
7484 new ICmpInst(FlippedStrictness->first, Op0, FlippedStrictness->second);
7485 NewCmp->setSameSign(FlippedStrictness->first.hasSameSign());
7504 I.setName(
I.getName() +
".not");
7515 Value *
A =
I.getOperand(0), *
B =
I.getOperand(1);
7516 assert(
A->getType()->isIntOrIntVectorTy(1) &&
"Bools only");
7522 switch (
I.getPredicate()) {
7531 switch (
I.getPredicate()) {
7541 switch (
I.getPredicate()) {
7550 return BinaryOperator::CreateXor(
A,
B);
7558 return BinaryOperator::CreateAnd(Builder.CreateNot(
A),
B);
7566 return BinaryOperator::CreateAnd(Builder.CreateNot(
B),
A);
7574 return BinaryOperator::CreateOr(Builder.CreateNot(
A),
B);
7582 return BinaryOperator::CreateOr(Builder.CreateNot(
B),
A);
7630 Value *NewX = Builder.CreateLShr(
X,
Y,
X->getName() +
".highbits");
7638 Value *
LHS = Cmp.getOperand(0), *
RHS = Cmp.getOperand(1);
7642 Value *V = Builder.CreateCmp(Pred,
X,
Y, Cmp.getName());
7644 I->copyIRFlags(&Cmp);
7645 Module *M = Cmp.getModule();
7647 M, Intrinsic::vector_reverse, V->getType());
7654 (
LHS->hasOneUse() ||
RHS->hasOneUse()))
7655 return createCmpReverse(Pred,
V1, V2);
7659 return createCmpReverse(Pred,
V1,
RHS);
7663 return createCmpReverse(Pred,
LHS, V2);
7672 Type *V1Ty =
V1->getType();
7674 V1Ty == V2->
getType() && (
LHS->hasOneUse() ||
RHS->hasOneUse())) {
7675 Value *NewCmp = Builder.CreateCmp(Pred,
V1, V2);
7688 Constant *ScalarC =
C->getSplatValue(
true);
7696 Value *NewCmp = Builder.CreateCmp(Pred,
V1,
C);
7707 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7713 if (
match(Op0, UAddOvResultPat) &&
7724 (Op0 ==
A || Op0 ==
B))
7734 if (!
I.getOperand(0)->getType()->isPointerTy() ||
7736 I.getParent()->getParent(),
7737 I.getOperand(0)->getType()->getPointerAddressSpace())) {
7741 if (
match(
I.getOperand(0),
7757 Value *Const =
I.getOperand(1);
7775 Type *VecEltTy = VecTy->getElementType();
7777 DL.getTypeSizeInBits(VecEltTy) * VecTy->getNumElements();
7778 if (!
DL.fitsInLegalInteger(ScalarBW))
7782 ? ConstantInt::get(ScalarTy, 0)
7785 Builder.CreateBitCast(Vec, ScalarTy), NewConst);
7797 if (
I.getType()->isVectorTy())
7820 if (!LHSTy || !LHSTy->getElementType()->isIntegerTy())
7823 LHSTy->getNumElements() * LHSTy->getElementType()->getIntegerBitWidth();
7825 if (!
DL.isLegalInteger(NumBits))
7829 auto *ScalarTy = Builder.getIntNTy(NumBits);
7830 LHS = Builder.CreateBitCast(
LHS, ScalarTy,
LHS->getName() +
".scalar");
7831 RHS = Builder.CreateBitCast(
RHS, ScalarTy,
RHS->getName() +
".scalar");
7887 bool IsIntMinPosion =
C->isAllOnesValue();
7899 CtxI, IsIntMinPosion
7900 ?
Builder.CreateICmpSGT(
X, AllOnesValue)
7902 X, ConstantInt::get(
X->getType(),
SMin + 1)));
7908 CtxI, IsIntMinPosion
7909 ?
Builder.CreateICmpSLT(
X, NullValue)
7911 X, ConstantInt::get(
X->getType(),
SMin)));
7938 auto CheckUGT1 = [](
const APInt &Divisor) {
return Divisor.ugt(1); };
7953 auto CheckNE0 = [](
const APInt &Shift) {
return !Shift.isZero(); };
7974 if (ShAmt >=
X->getType()->getScalarSizeInBits())
7976 if (canEvaluateShifted(Op1, ShAmt,
false,
7978 Value *NewOp1 = getShiftedValue(Op1, ShAmt,
false,
7986 if (ShAmt >=
X->getType()->getScalarSizeInBits())
7988 if (canEvaluateShifted(Op1, ShAmt,
false,
7990 Value *NewOp1 = getShiftedValue(Op1, ShAmt,
false,
8001 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
8008 if (Op0Cplxity < Op1Cplxity) {
8023 if (
Value *V = dyn_castNegVal(SelectTrue)) {
8024 if (V == SelectFalse)
8026 }
else if (
Value *V = dyn_castNegVal(SelectFalse)) {
8027 if (V == SelectTrue)
8087 if (
C->isNonNegative())
8091 ConstantInt::get(
X->getType(), ~*
C));
8097 if (
C->isNonNegative())
8101 ConstantInt::get(
X->getType(), ~*
C));
8157 if (
I.isCommutative()) {
8158 if (
auto Pair = matchSymmetricPair(
I.getOperand(0),
I.getOperand(1))) {
8187 (Op0->
hasOneUse() || Op1->hasOneUse())) {
8215 bool I0NUW = I0->hasNoUnsignedWrap();
8216 bool I1NUW = I1->hasNoUnsignedWrap();
8217 bool I0NSW = I0->hasNoSignedWrap();
8218 bool I1NSW = I1->hasNoSignedWrap();
8222 ((I0NUW || I0NSW) && (I1NUW || I1NSW)))) {
8224 ConstantInt::get(Op0->
getType(), 0));
8231 assert(Op1->getType()->isPointerTy() &&
8232 "Comparing pointer with non-pointer?");
8256 Type *SmallType =
X->getType();
8258 if (Mask->isMask(SmallWidth) &&
8259 shouldChangeType(
I.getOperand(0)->getType(), SmallType)) {
8261 return new ICmpInst(
I.getUnsignedPredicate(), NewTrunc,
X);
8279 bool ConsumesOp0, ConsumesOp1;
8282 (ConsumesOp0 || ConsumesOp1)) {
8285 assert(InvOp0 && InvOp1 &&
8286 "Mismatch between isFreeToInvert and getFreelyInverted");
8287 return new ICmpInst(
I.getSwappedPredicate(), InvOp0, InvOp1);
8299 if (AddI->
getOpcode() == Instruction::Add &&
8300 OptimizeOverflowCheck(Instruction::Add,
false,
X,
Y, *AddI,
8301 Result, Overflow)) {
8321 if ((
I.isUnsigned() ||
I.isEquality()) &&
8324 Y->getType()->getScalarSizeInBits() == 1 &&
8325 (Op0->
hasOneUse() || Op1->hasOneUse())) {
8332 unsigned ShiftOpc = ShiftI->
getOpcode();
8333 if ((ExtOpc == Instruction::ZExt && ShiftOpc == Instruction::LShr) ||
8334 (ExtOpc == Instruction::SExt && ShiftOpc == Instruction::AShr)) {
8368 if (EVI->getIndices()[0] == 0 && ACXI->getCompareOperand() == Op1 &&
8375 if (
I.getType()->isVectorTy())
8387 const APInt *C1, *C2;
8394 Type *InputTy =
A->getType();
8401 TruncC1.
setBit(InputBitWidth - 1);
8405 ConstantInt::get(InputTy, C2->
trunc(InputBitWidth)));
8425 if (MantissaWidth == -1)
8432 if (
I.isEquality()) {
8434 bool IsExact =
false;
8435 APSInt RHSCvt(IntWidth, LHSUnsigned);
8444 if (*RHS != RHSRoundInt) {
8464 if ((
int)IntWidth > MantissaWidth) {
8466 int Exp =
ilogb(*RHS);
8469 if (MaxExponent < (
int)IntWidth - !LHSUnsigned)
8475 if (MantissaWidth <= Exp && Exp <= (
int)IntWidth - !LHSUnsigned)
8484 assert(!RHS->isNaN() &&
"NaN comparison not already folded!");
8487 switch (
I.getPredicate()) {
8578 APSInt RHSInt(IntWidth, LHSUnsigned);
8581 if (!RHS->isZero()) {
8596 if (RHS->isNegative())
8602 if (RHS->isNegative())
8608 if (RHS->isNegative())
8615 if (!RHS->isNegative())
8621 if (RHS->isNegative())
8627 if (RHS->isNegative())
8633 if (RHS->isNegative())
8640 if (!RHS->isNegative())
8659 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
8670 unsigned Pred =
I.getPredicate();
8678 if (!Res00 || !Res01 || !Res10 || !Res11)
8687 std::bitset<4>
Table;
8745 if (
C->isNegative())
8746 Pred =
I.getSwappedPredicate();
8773 "X ord/uno NaN should be folded away by simplifyFCmpInst()");
8779 bool RoundDown =
false;
8800 auto NextValue = [](
const APFloat &
Value,
bool RoundDown) {
8802 NextValue.
next(RoundDown);
8806 APFloat NextCValue = NextValue(*CValue, RoundDown);
8811 APFloat ExtCValue = ConvertFltSema(*CValue, DestFltSema);
8812 APFloat ExtNextCValue = ConvertFltSema(NextCValue, DestFltSema);
8819 APFloat PrevCValue = NextValue(*CValue, !RoundDown);
8820 APFloat Bias = ConvertFltSema(*CValue - PrevCValue, DestFltSema);
8822 ExtNextCValue = ExtCValue + Bias;
8829 C.getType()->getScalarType()->getFltSemantics();
8832 APFloat MidValue = ConvertFltSema(ExtMidValue, SrcFltSema);
8833 if (MidValue != *CValue)
8834 ExtMidValue.
next(!RoundDown);
8842 if (ConvertFltSema(ExtMidValue, SrcFltSema).isInfinity())
8846 APFloat NextExtMidValue = NextValue(ExtMidValue, RoundDown);
8847 if (ConvertFltSema(NextExtMidValue, SrcFltSema).
isFinite())
8852 ConstantFP::get(DestType, ExtMidValue),
"", &
I);
8865 if (!
C->isPosZero()) {
8866 if (!
C->isSmallestNormalized())
8879 switch (
I.getPredicate()) {
8905 switch (
I.getPredicate()) {
8930 assert(!
I.hasNoNaNs() &&
"fcmp should have simplified");
8935 assert(!
I.hasNoNaNs() &&
"fcmp should have simplified");
8949 return replacePredAndOp0(&
I,
I.getPredicate(),
X);
8972 I.setHasNoInfs(
false);
8974 switch (
I.getPredicate()) {
9019 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
9024 Pred =
I.getSwappedPredicate();
9033 return new FCmpInst(Pred, Op0, Zero,
"", &
I);
9069 I.getFunction()->getDenormalMode(
9076 I.setHasNoNaNs(
true);
9101 if (MantissaWidth != -1 &&
ilogb(*
C) < MantissaWidth) {
9103 I.setPredicate(
I.getSwappedPredicate());
9140 if (!IsStrictLt && !IsStrictGt && !IsGe)
9162 }
else if (
match(FAbsArg,
9170 if (
A->getType() !=
B->getType())
9185 Type *OpType =
LHS->getType();
9191 if (!FloorX && !CeilX) {
9195 Pred =
I.getSwappedPredicate();
9271 if (!
I || !(
I->getOpcode() == Instruction::SIToFP ||
9272 I->getOpcode() == Instruction::UIToFP))
9275 bool IsUnsigned =
I->getOpcode() == Instruction::UIToFP;
9276 unsigned BitWidth =
I->getOperand(0)->getType()->getScalarSizeInBits();
9299 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
9301 SQ.getWithInstruction(&
I)))
9306 assert(OpType == Op1->getType() &&
"fcmp with different-typed operands?");
9331 if (
I.isCommutative()) {
9332 if (
auto Pair = matchSymmetricPair(
I.getOperand(0),
I.getOperand(1))) {
9354 return new FCmpInst(
I.getSwappedPredicate(),
X,
Y,
"", &
I);
9370 bool IsRedundantMinMaxClamp =
9432 X->getType()->isIntOrIntVectorTy() &&
9433 !
F.getDenormalMode(Op1->getType()->getScalarType()->getFltSemantics())
9434 .inputsMayBeZero()) {
9442 Type *IntTy =
X->getType();
9443 const APInt &SignMask =
~APInt::getSignMask(IntTy->getScalarSizeInBits());
9444 Value *MaskX =
Builder.CreateAnd(
X, ConstantInt::get(IntTy, SignMask));
9454 case Instruction::Select:
9462 case Instruction::FSub:
9467 case Instruction::PHI:
9471 case Instruction::SIToFP:
9472 case Instruction::UIToFP:
9476 case Instruction::FDiv:
9480 case Instruction::Load:
9486 case Instruction::FPTrunc:
9513 return new FCmpInst(
I.getSwappedPredicate(),
X, NegC,
"", &
I);
9527 X->getType() ==
Y->getType())
9538 X->getType()->getScalarType()->getFltSemantics();
9574 Constant *NewC = ConstantFP::get(
X->getType(), TruncC);
9587 Type *IntType =
Builder.getIntNTy(
X->getType()->getScalarSizeInBits());
9600 Value *CanonLHS =
nullptr;
9603 if (CanonLHS == Op1)
9604 return new FCmpInst(Pred, Op1, Op1,
"", &
I);
9606 Value *CanonRHS =
nullptr;
9609 if (CanonRHS == Op0)
9610 return new FCmpInst(Pred, Op0, Op0,
"", &
I);
9613 if (CanonLHS && CanonRHS)
9614 return new FCmpInst(Pred, CanonLHS, CanonRHS,
"", &
I);
9617 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 * foldCmpLoadFromIndexedGlobal(LoadInst *LI, GetElementPtrInst *GEP, CmpInst &ICI, ConstantInt *AndCst=nullptr)
This is called when we see this pattern: cmp pred (load (gep GV, ...)), cmpcst where GV is a global v...
Instruction * foldICmpSubConstant(ICmpInst &Cmp, BinaryOperator *Sub, const APInt &C)
Fold icmp (sub X, Y), C.
Instruction * foldICmpWithClamp(ICmpInst &Cmp, Value *X, MinMaxIntrinsic *Min)
Match and fold patterns like: icmp eq/ne X, min(max(X, Lo), Hi) which represents a range check and ca...
Instruction * foldICmpInstWithConstantNotInt(ICmpInst &Cmp)
Handle icmp with constant (but not simple integer constant) RHS.
bool SimplifyDemandedBits(Instruction *I, unsigned Op, const APInt &DemandedMask, KnownBits &Known, const SimplifyQuery &Q, unsigned Depth=0) override
This form of SimplifyDemandedBits simplifies the specified instruction operand if possible,...
Instruction * foldICmpShlConstConst(ICmpInst &I, Value *ShAmt, const APInt &C1, const APInt &C2)
Handle "(icmp eq/ne (shl AP2, A), AP1)" -> (icmp eq/ne A, TrailingZeros(AP1) - TrailingZeros(AP2)).
Value * reassociateShiftAmtsOfTwoSameDirectionShifts(BinaryOperator *Sh0, const SimplifyQuery &SQ, bool AnalyzeForSignBitExtraction=false)
Instruction * foldICmpEqIntrinsicWithConstant(ICmpInst &ICI, IntrinsicInst *II, const APInt &C)
Fold an equality icmp with LLVM intrinsic and constant operand.
Instruction * FoldOpIntoSelect(Instruction &Op, SelectInst *SI, bool FoldWithMultiUse=false, bool SimplifyBothArms=false)
Given an instruction with a select as one operand and a constant as the other operand,...
Value * foldMultiplicationOverflowCheck(ICmpInst &Cmp)
Fold (-1 u/ x) u< y ((x * y) ?
Instruction * foldICmpWithConstant(ICmpInst &Cmp)
Fold icmp Pred X, C.
OverflowResult computeOverflow(Instruction::BinaryOps BinaryOp, bool IsSigned, Value *LHS, Value *RHS, Instruction *CtxI) const
CmpInst * canonicalizeICmpPredicate(CmpInst &I)
If we have a comparison with a non-canonical predicate, if we can update all the users,...
Instruction * eraseInstFromFunction(Instruction &I) override
Combiner aware instruction erasure.
Instruction * foldICmpWithZero(ICmpInst &Cmp)
Instruction * foldICmpBinOpEqualityWithConstant(ICmpInst &Cmp, BinaryOperator *BO, const APInt &C)
Fold an icmp equality instruction with binary operator LHS and constant RHS: icmp eq/ne BO,...
Instruction * foldICmpUsingBoolRange(ICmpInst &I)
If one operand of an icmp is effectively a bool (value range of {0,1}), then try to reduce patterns b...
Instruction * foldICmpWithTrunc(ICmpInst &Cmp)
Instruction * foldCmpSelectOfConstants(CmpInst &I)
Fold fcmp/icmp pred (select C1, TV1, FV1), (select C2, TV2, FV2) where all true/false values are cons...
Instruction * foldICmpIntrinsicWithConstant(ICmpInst &ICI, IntrinsicInst *II, const APInt &C)
Fold an icmp with LLVM intrinsic and constant operand: icmp Pred II, C.
bool matchThreeWayIntCompare(SelectInst *SI, Value *&LHS, Value *&RHS, ConstantInt *&Less, ConstantInt *&Equal, ConstantInt *&Greater)
Match a select chain which produces one of three values based on whether the LHS is less than,...
const InstCombineCLOptions & CLOpts
Instruction * visitFCmpInst(FCmpInst &I)
Instruction * foldICmpUsingKnownBits(ICmpInst &Cmp)
Try to fold the comparison based on range information we can get by checking whether bits are known t...
Instruction * foldICmpDivConstant(ICmpInst &Cmp, BinaryOperator *Div, const APInt &C)
Fold icmp ({su}div X, Y), C.
Instruction * foldIRemByPowerOfTwoToBitTest(ICmpInst &I)
If we have: icmp eq/ne (urem/srem x, y), 0 iff y is a power-of-two, we can replace this with a bit te...
Instruction * foldFCmpIntToFPConst(FCmpInst &I, Instruction *LHSI, Constant *RHSC)
Fold fcmp ([us]itofp x, cst) if possible.
Instruction * foldICmpUDivConstant(ICmpInst &Cmp, BinaryOperator *UDiv, const APInt &C)
Fold icmp (udiv X, Y), C.
Instruction * foldICmpAddOpConst(Value *X, const APInt &C, CmpPredicate Pred)
Fold "icmp pred (X+C), X".
Instruction * foldICmpWithCastOp(ICmpInst &ICmp)
Handle icmp (cast x), (cast or constant).
Instruction * foldICmpTruncConstant(ICmpInst &Cmp, TruncInst *Trunc, const APInt &C)
Fold icmp (trunc X), C.
Instruction * foldICmpAddConstant(ICmpInst &Cmp, BinaryOperator *Add, const APInt &C)
Fold icmp (add X, Y), C.
Instruction * foldICmpMulConstant(ICmpInst &Cmp, BinaryOperator *Mul, const APInt &C)
Fold icmp (mul X, Y), C.
Instruction * foldICmpCommutative(CmpPredicate Pred, Value *Op0, Value *Op1, ICmpInst &CtxI)
Instruction * tryFoldInstWithCtpopWithNot(Instruction *I)
Instruction * foldICmpXorConstant(ICmpInst &Cmp, BinaryOperator *Xor, const APInt &C)
Fold icmp (xor X, Y), C.
Instruction * foldSelectICmp(CmpPredicate Pred, SelectInst *SI, Value *RHS, const ICmpInst &I)
Instruction * foldICmpInstWithConstantAllowPoison(ICmpInst &Cmp, const APInt &C)
Try to fold integer comparisons with a constant operand: icmp Pred X, C where X is some kind of instr...
Instruction * foldIsMultipleOfAPowerOfTwo(ICmpInst &Cmp)
Fold icmp eq (num + mask) & ~mask, num to icmp eq (and num, mask), 0 Where mask is a low bit mask.
Instruction * foldICmpAndShift(ICmpInst &Cmp, BinaryOperator *And, const APInt &C1, const APInt &C2)
Fold icmp (and (sh X, Y), C2), C1.
Instruction * foldICmpBinOpWithConstantViaTruthTable(ICmpInst &Cmp, BinaryOperator *BO, const APInt &C)
Instruction * foldICmpInstWithConstant(ICmpInst &Cmp)
Try to fold integer comparisons with a constant operand: icmp Pred X, C where X is some kind of instr...
Instruction * foldICmpXorShiftConst(ICmpInst &Cmp, BinaryOperator *Xor, const APInt &C)
For power-of-2 C: ((X s>> ShiftC) ^ X) u< C --> (X + C) u< (C << 1) ((X s>> ShiftC) ^ X) u> (C - 1) -...
Instruction * foldICmpShlConstant(ICmpInst &Cmp, BinaryOperator *Shl, const APInt &C)
Fold icmp (shl X, Y), C.
Instruction * foldICmpAndConstant(ICmpInst &Cmp, BinaryOperator *And, const APInt &C)
Fold icmp (and X, Y), C.
Instruction * foldICmpEquality(ICmpInst &Cmp)
Instruction * foldICmpWithMinMax(Instruction &I, MinMaxIntrinsic *MinMax, Value *Z, CmpPredicate Pred)
Fold icmp Pred min|max(X, Y), Z.
bool dominatesAllUses(const Instruction *DI, const Instruction *UI, const BasicBlock *DB) const
True when DB dominates all uses of DI except UI.
bool foldAllocaCmp(AllocaInst *Alloca)
Instruction * visitICmpInst(ICmpInst &I)
Instruction * foldICmpWithDominatingICmp(ICmpInst &Cmp)
Canonicalize icmp instructions based on dominating conditions.
bool replacedSelectWithOperand(SelectInst *SI, const ICmpInst *Icmp, const unsigned SIOpd)
Try to replace select with select operand SIOpd in SI-ICmp sequence.
Instruction * foldICmpShrConstConst(ICmpInst &I, Value *ShAmt, const APInt &C1, const APInt &C2)
Handle "(icmp eq/ne (ashr/lshr AP2, A), AP1)" -> (icmp eq/ne A, Log2(AP2/AP1)) -> (icmp eq/ne A,...
void freelyInvertAllUsersOf(Value *V, Value *IgnoredUser=nullptr)
Freely adapt every user of V as-if V was changed to !V.
Instruction * foldICmpAndConstConst(ICmpInst &Cmp, BinaryOperator *And, const APInt &C1)
Fold icmp (and X, C2), C1.
Instruction * foldICmpBitCast(ICmpInst &Cmp)
Instruction * foldGEPICmp(GEPOperator *GEPLHS, Value *RHS, CmpPredicate Cond, Instruction &I)
Fold comparisons between a GEP instruction and something else.
The core instruction combiner logic.
OverflowResult computeOverflowForSignedMul(const Value *LHS, const Value *RHS, const Instruction *CtxI) const
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)
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
cst_pred_ty< is_negated_power2_or_zero > m_NegatedPower2OrZero()
Match a integer or vector negated power-of-2.
NoWrapTrunc_match< OpTy, TruncInst::NoUnsignedWrap > m_NUWTrunc(const OpTy &Op)
Matches trunc nuw.
cst_pred_ty< custom_checkfn< APInt > > m_CheckedInt(function_ref< bool(const APInt &)> CheckFn)
Match an integer or vector where CheckFn(ele) for each element is true.
SelectLike_match< CondTy, LTy, RTy > m_SelectLike(const CondTy &C, const LTy &TrueC, const RTy &FalseC)
Matches a value that behaves like a boolean-controlled select, i.e.
cst_pred_ty< is_lowbit_mask_or_zero > m_LowBitMaskOrZero()
Match an integer or vector with only the low bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
match_combine_or< BinaryOp_match< LHS, RHS, Instruction::Add >, DisjointOr_match< LHS, RHS > > m_AddLike(const LHS &L, const RHS &R)
Match either "add" or "or disjoint".
CastInst_match< OpTy, UIToFPInst > m_UIToFP(const OpTy &Op)
CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
cstfp_pred_ty< is_finitenonzero > m_FiniteNonZero()
Match a finite non-zero FP constant.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)
auto m_SMin(const Opnd0 &Op0, const Opnd1 &Op1)
auto m_FAbs(const Opnd0 &Op0)
Signum_match< Val_t > m_Signum(const Val_t &V)
Matches a signum pattern.
CastInst_match< OpTy, SIToFPInst > m_SIToFP(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > > m_ZExtOrSExt(const OpTy &Op)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
UAddWithOverflow_match< LHS_t, RHS_t, Sum_t > m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S)
Match an icmp instruction checking for unsigned overflow on addition.
BinOpPred_match< LHS, RHS, is_irem_op > m_IRem(const LHS &L, const RHS &R)
Matches integer remainder operations.
auto m_MaxOrMin(const Opnd0 &Op0, const Opnd1 &Op1)
CastInst_match< OpTy, FPTruncInst > m_FPTrunc(const OpTy &Op)
auto m_Undef()
Match an arbitrary undef constant.
auto m_VecReverse(const Opnd0 &Op0)
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
ElementWiseBitCast_match< OpTy > m_ElementWiseBitCast(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
CastOperator_match< OpTy, Instruction::PtrToInt > m_PtrToInt(const OpTy &Op)
Matches PtrToInt.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
cst_pred_ty< icmp_pred_with_threshold > m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold)
Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
This is an optimization pass for GlobalISel generic memory operations.
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
@ NeverOverflows
Never overflows.
@ AlwaysOverflowsHigh
Always overflows in the direction of signed/unsigned max value.
@ AlwaysOverflowsLow
Always overflows in the direction of signed/unsigned min value.
@ MayOverflow
May or may not overflow.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isKnownNeverInfinity(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point scalar value is not an infinity or if the floating-point vector val...
LLVM_ABI bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS, bool &TrueIfSigned)
Given an exploded icmp instruction, return true if the comparison only checks the sign bit.
@ Known
Known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ BinaryOp
One of the operands is a binary op.
LLVM_ABI Value * stripNullTest(Value *V)
Returns the inner value X if the expression has the form f(X) where f(X) == 0 if and only if X == 0,...
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
LLVM_ABI Value * simplifyFCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q)
Given operands for an FCmpInst, fold the result or return null.
int ilogb(const APFloat &Arg)
Returns the exponent of the internal representation of the APFloat.
LLVM_ABI bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Return true if the given value is known to have exactly one bit set when defined.
LLVM_ABI bool MaskedValueIsZero(const Value *V, const APInt &Mask, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if 'V & Mask' is known to be zero.
LLVM_ABI Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Function *CtxF=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
LLVM_ABI Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for an Add, fold the result or return null.
LLVM_ABI Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)
Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
LLVM_ABI Value * emitGEPOffset(IRBuilderBase *Builder, const DataLayout &DL, User *GEP, bool NoAssumptions=false)
Given a getelementptr instruction/constantexpr, emit the code necessary to compute the offset from th...
constexpr unsigned MaxAnalysisRecursionDepth
LLVM_ABI Constant * ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op, const DataLayout &DL)
Attempt to constant fold a unary operation with the specified operand.
LLVM_ABI bool isKnownNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the given value is known be negative (i.e.
SelectPatternFlavor
Specific patterns of select instructions we can match.
@ SPF_FMAXNUM
Floating point minnum.
@ SPF_FMINNUM
Unsigned maximum.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI bool impliesPoison(const Value *ValAssumedPoison, const Value *V)
Return true if V is poison given that ValAssumedPoison is already poison.
LLVM_ABI LinearExpression decomposeLinearExpression(const DataLayout &DL, Value *Ptr)
Decompose a pointer into a linear expression.
LLVM_ABI bool isFinite(const Loop *L)
Return true if this loop can be assumed to run for a finite number of iterations.
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode RM)
Returns: X * 2^Exp for integral exponents.
LLVM_ABI SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)
Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind and providing the out param...
LLVM_ABI bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Value * simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an ICmpInst, fold the result or return null.
LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
LLVM_ABI Constant * ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset, const DataLayout &DL)
Extract value of C at the given Offset reinterpreted as Ty.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
LLVM_ABI Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
@ UMin
Unsigned integer min implemented in terms of select(cmp()).
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ SMax
Signed integer max implemented in terms of select(cmp()).
@ SMin
Signed integer min implemented in terms of select(cmp()).
@ Sub
Subtraction of integers.
@ UMax
Unsigned integer max implemented in terms of select(cmp()).
LLVM_ABI bool isKnownNonEqual(const Value *V1, const Value *V2, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the given values are known to be non-equal when defined.
DWARFExpression::Operation Op
LLVM_ABI bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, unsigned MaxUsesToExplore=0)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
constexpr unsigned BitWidth
LLVM_ABI Constant * getLosslessInvCast(Constant *C, Type *InvCastTo, unsigned CastOp, const DataLayout &DL, PreservedCastFlags *Flags=nullptr)
Try to cast C to InvC losslessly, satisfying CastOp(InvC) equals C, or CastOp(InvC) is a refined valu...
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
LLVM_ABI bool isKnownNeverInfOrNaN(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point value can never contain a NaN or infinity.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isKnownNeverNaN(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...
LLVM_ABI std::optional< std::pair< CmpPredicate, Constant * > > getFlippedStrictnessPredicateAndConstant(CmpPredicate Pred, Constant *C)
Convert an integer comparison with a constant RHS into an equivalent form with the strictness flipped...
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
LLVM_ABI bool isKnownPositive(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the given value is known be positive (i.e.
LLVM_ABI bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the give value is known to be non-negative.
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
LLVM_ABI std::optional< bool > isImpliedCondition(const Value *LHS, const Value *RHS, const DataLayout &DL, bool LHSIsTrue=true, unsigned Depth=0)
Return true if RHS is known to be implied true by LHS.
LLVM_ABI std::optional< DecomposedBitTest > decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate Pred, bool LookThroughTrunc=true, bool AllowNonZeroC=false, bool DecomposeAnd=false)
Decompose an icmp into the form ((X & Mask) pred C) if possible.
LLVM_ABI ConstantRange computeConstantRange(const Value *V, bool ForSigned, const SimplifyQuery &SQ, unsigned Depth=0)
Determine the possible constant range of an integer or vector of integer value.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Value * materialize(InstCombiner::BuilderTy &Builder) const
static OffsetResult select(Value *Cond, Value *TrueV, Value *FalseV, Instruction *MDFrom)
static OffsetResult value(Value *V)
static OffsetResult invalid()
This callback is used in conjunction with PointerMayBeCaptured.
static CommonPointerBase compute(Value *LHS, Value *RHS)
Represent subnormal handling kind for floating point instruction inputs and outputs.
@ PreserveSign
The sign of a flushed-to-zero number is preserved in the sign of 0.
@ PositiveZero
Denormals are flushed to positive zero.
static constexpr DenormalMode getIEEE()
bool isNonNegative() const
Returns true if this value is known to be non-negative.
bool isZero() const
Returns true if value is all zero.
unsigned countMinTrailingZeros() const
Returns the minimum number of trailing zero bits.
unsigned countMaxTrailingZeros() const
Returns the maximum number of trailing zero bits possible.
APInt getSignedMaxValue() const
Return the maximal signed value possible given these KnownBits.
unsigned countMaxPopulation() const
Returns the maximum number of bits that could be one.
bool isConstant() const
Returns true if we know the value of all bits.
unsigned countMinLeadingZeros() const
Returns the minimum number of leading zero bits.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
APInt getMinValue() const
Return the minimal unsigned value possible given these KnownBits.
bool isStrictlyPositive() const
Returns true if this value is known to be positive.
bool isNegative() const
Returns true if this value is known to be negative.
unsigned countMinPopulation() const
Returns the number of bits known to be one.
APInt getSignedMinValue() const
Return the minimal signed value possible given these KnownBits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
Linear expression BasePtr + Index * Scale + Offset.
SelectPatternFlavor Flavor
static bool isMinOrMax(SelectPatternFlavor SPF)
When implementing this min/max pattern as fcmp; select, does the fcmp have to be ordered?
SimplifyQuery getWithInstruction(const Instruction *I) const
A MapVector that performs no allocations if smaller than a certain size.
Capture information for a specific Use.