40#define DEBUG_TYPE "instcombine"
52 bool IsSigned =
false) {
55 Result = In1.
sadd_ov(In2, Overflow);
57 Result = In1.
uadd_ov(In2, Overflow);
65 bool IsSigned =
false) {
68 Result = In1.
ssub_ov(In2, Overflow);
70 Result = In1.
usub_ov(In2, Overflow);
78 for (
auto *U :
I.users())
100 }
else if (
C.isAllOnes()) {
126 if (LI->
isVolatile() || !GV || !GV->isConstant() ||
127 !GV->hasDefinitiveInitializer())
131 TypeSize EltSize =
DL.getTypeStoreSize(EltTy);
147 if (!ConstOffset.
ult(Stride))
155 uint64_t ArrayElementCount =
161 enum { Overdefined = -3, Undefined = -2 };
170 int FirstTrueElement = Undefined, SecondTrueElement = Undefined;
174 int FirstFalseElement = Undefined, SecondFalseElement = Undefined;
182 int TrueRangeEnd = Undefined, FalseRangeEnd = Undefined;
187 uint64_t MagicBitvector = 0;
192 for (
unsigned i = 0, e = ArrayElementCount; i != e; ++i,
Offset += Stride) {
206 CompareRHS,
DL, &
TLI);
214 if (TrueRangeEnd == (
int)i - 1)
216 if (FalseRangeEnd == (
int)i - 1)
233 if (FirstTrueElement == Undefined)
234 FirstTrueElement = TrueRangeEnd = i;
237 if (SecondTrueElement == Undefined)
238 SecondTrueElement = i;
240 SecondTrueElement = Overdefined;
243 if (TrueRangeEnd == (
int)i - 1)
246 TrueRangeEnd = Overdefined;
250 if (FirstFalseElement == Undefined)
251 FirstFalseElement = FalseRangeEnd = i;
254 if (SecondFalseElement == Undefined)
255 SecondFalseElement = i;
257 SecondFalseElement = Overdefined;
260 if (FalseRangeEnd == (
int)i - 1)
263 FalseRangeEnd = Overdefined;
268 if (i < 64 && IsTrueForElt)
269 MagicBitvector |= 1ULL << i;
274 if ((i & 8) == 0 && i >= 64 && SecondTrueElement == Overdefined &&
275 SecondFalseElement == Overdefined && TrueRangeEnd == Overdefined &&
276 FalseRangeEnd == Overdefined)
290 auto MaskIdx = [&](
Value *Idx) {
294 Idx =
Builder.CreateAnd(Idx, Mask);
301 if (SecondTrueElement != Overdefined) {
304 if (FirstTrueElement == Undefined)
307 Value *FirstTrueIdx = ConstantInt::get(Idx->
getType(), FirstTrueElement);
310 if (SecondTrueElement == Undefined)
315 Value *SecondTrueIdx = ConstantInt::get(Idx->
getType(), SecondTrueElement);
317 return BinaryOperator::CreateOr(C1, C2);
322 if (SecondFalseElement != Overdefined) {
325 if (FirstFalseElement == Undefined)
328 Value *FirstFalseIdx = ConstantInt::get(Idx->
getType(), FirstFalseElement);
331 if (SecondFalseElement == Undefined)
336 Value *SecondFalseIdx =
337 ConstantInt::get(Idx->
getType(), SecondFalseElement);
339 return BinaryOperator::CreateAnd(C1, C2);
344 if (TrueRangeEnd != Overdefined) {
345 assert(TrueRangeEnd != FirstTrueElement &&
"Should emit single compare");
349 if (FirstTrueElement) {
351 Idx =
Builder.CreateAdd(Idx, Offs);
355 ConstantInt::get(Idx->
getType(), TrueRangeEnd - FirstTrueElement + 1);
360 if (FalseRangeEnd != Overdefined) {
361 assert(FalseRangeEnd != FirstFalseElement &&
"Should emit single compare");
364 if (FirstFalseElement) {
366 Idx =
Builder.CreateAdd(Idx, Offs);
370 ConstantInt::get(Idx->
getType(), FalseRangeEnd - FirstFalseElement);
383 if (ArrayElementCount <= Idx->
getType()->getIntegerBitWidth())
386 Ty =
DL.getSmallestLegalIntType(
Init->getContext(), ArrayElementCount);
391 V =
Builder.CreateLShr(ConstantInt::get(Ty, MagicBitvector), V);
392 V =
Builder.CreateAnd(ConstantInt::get(Ty, 1), V);
417 while (!WorkList.
empty()) {
420 while (!WorkList.
empty()) {
421 if (Explored.
size() >= 100)
439 if (!
GEP->isInBounds() ||
count_if(
GEP->indices(), IsNonConst) > 1)
447 if (WorkList.
back() == V) {
463 for (
auto *PN : PHIs)
464 for (
Value *
Op : PN->incoming_values())
472 for (
Value *Val : Explored) {
478 if (Inst ==
Base || Inst ==
PHI || !Inst || !
PHI ||
482 if (
PHI->getParent() == Inst->getParent())
492 bool Before =
true) {
500 I = &*std::next(
I->getIterator());
501 Builder.SetInsertPoint(
I);
506 BasicBlock &Entry =
A->getParent()->getEntryBlock();
507 Builder.SetInsertPoint(&Entry, Entry.getFirstInsertionPt());
529 Base->getContext(),
DL.getIndexTypeSizeInBits(Start->getType()));
535 for (
Value *Val : Explored) {
543 PHI->getName() +
".idx",
PHI->getIterator());
548 for (
Value *Val : Explored) {
557 NewInsts[
GEP] = OffsetV;
559 NewInsts[
GEP] = Builder.CreateAdd(
560 Op, OffsetV,
GEP->getOperand(0)->getName() +
".add",
572 for (
Value *Val : Explored) {
579 for (
unsigned I = 0,
E =
PHI->getNumIncomingValues();
I <
E; ++
I) {
580 Value *NewIncoming =
PHI->getIncomingValue(
I);
582 auto It = NewInsts.
find(NewIncoming);
583 if (It != NewInsts.
end())
584 NewIncoming = It->second;
591 for (
Value *Val : Explored) {
597 Value *NewVal = Builder.CreateGEP(Builder.getInt8Ty(),
Base, NewInsts[Val],
598 Val->getName() +
".ptr", NW);
605 return NewInsts[Start];
691 if (
Base.Ptr == RHS && CanFold(
Base.LHSNW) && !
Base.isExpensive()) {
695 EmitGEPOffsets(
Base.LHSGEPs,
Base.LHSNW, IdxTy,
true);
703 RHS->getType()->getPointerAddressSpace())) {
734 if (GEPLHS->
getOperand(0) != GEPRHS->getOperand(0)) {
735 bool IndicesTheSame =
738 GEPRHS->getPointerOperand()->getType() &&
742 if (GEPLHS->
getOperand(i) != GEPRHS->getOperand(i)) {
743 IndicesTheSame =
false;
749 if (IndicesTheSame &&
757 if (GEPLHS->
isInBounds() && GEPRHS->isInBounds() &&
759 (GEPRHS->hasAllConstantIndices() || GEPRHS->hasOneUse()) &&
763 Value *LOffset = EmitGEPOffset(GEPLHS);
764 Value *ROffset = EmitGEPOffset(GEPRHS);
771 if (LHSIndexTy != RHSIndexTy) {
774 ROffset =
Builder.CreateTrunc(ROffset, LHSIndexTy);
776 LOffset =
Builder.CreateTrunc(LOffset, RHSIndexTy);
785 if (GEPLHS->
getOperand(0) == GEPRHS->getOperand(0) &&
789 unsigned NumDifferences = 0;
790 unsigned DiffOperand = 0;
791 for (
unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i)
792 if (GEPLHS->
getOperand(i) != GEPRHS->getOperand(i)) {
794 Type *RHSType = GEPRHS->getOperand(i)->getType();
805 if (NumDifferences++)
810 if (NumDifferences == 0)
818 Value *RHSV = GEPRHS->getOperand(DiffOperand);
819 return NewICmp(NW, LHSV, RHSV);
823 if (
Base.Ptr && !
Base.isExpensive()) {
825 bool DoFold = CanFold(
Base.LHSNW &
Base.RHSNW);
827 if (!DoFold &&
Base.Ptr->getType()->isPointerTy()) {
831 unsigned BW =
DL.getIndexTypeSizeInBits(GEPLHS->
getType());
836 DL, LOff,
true) ==
Base.Ptr &&
837 RHS->stripAndAccumulateConstantOffsets(
838 DL, ROff,
true) ==
Base.Ptr)
850 return NewICmp(
Base.LHSNW &
Base.RHSNW, L, R);
877 bool Captured =
false;
882 CmpCaptureTracker(
AllocaInst *Alloca) : Alloca(Alloca) {}
884 void tooManyUses()
override { Captured =
true; }
896 ICmps[ICmp] |= 1u << U->getOperandNo();
905 CmpCaptureTracker Tracker(Alloca);
907 if (Tracker.Captured)
911 for (
auto [ICmp,
Operands] : Tracker.ICmps) {
917 auto *Res = ConstantInt::get(ICmp->getType(),
943 assert(!!
C &&
"C should not be zero!");
959 ConstantInt::get(
X->getType(), -
C));
971 ConstantInt::get(
X->getType(),
SMax -
C));
982 ConstantInt::get(
X->getType(),
SMax - (
C - 1)));
991 assert(
I.isEquality() &&
"Cannot fold icmp gt/lt");
994 if (
I.getPredicate() ==
I.ICMP_NE)
996 return new ICmpInst(Pred, LHS, RHS);
1015 return getICmp(
I.ICMP_UGT,
A,
1016 ConstantInt::get(
A->getType(), AP2.
logBase2()));
1028 if (IsAShr && AP1 == AP2.
ashr(Shift)) {
1032 return getICmp(
I.ICMP_UGE,
A, ConstantInt::get(
A->getType(), Shift));
1033 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1034 }
else if (AP1 == AP2.
lshr(Shift)) {
1035 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1041 auto *TorF = ConstantInt::get(
I.getType(),
I.getPredicate() ==
I.ICMP_NE);
1050 assert(
I.isEquality() &&
"Cannot fold icmp gt/lt");
1053 if (
I.getPredicate() ==
I.ICMP_NE)
1055 return new ICmpInst(Pred, LHS, RHS);
1064 if (!AP1 && AP2TrailingZeros != 0)
1067 ConstantInt::get(
A->getType(), AP2.
getBitWidth() - AP2TrailingZeros));
1075 if (Shift > 0 && AP2.
shl(Shift) == AP1)
1076 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1080 auto *TorF = ConstantInt::get(
I.getType(),
I.getPredicate() ==
I.ICMP_NE);
1109 if (NewWidth != 7 && NewWidth != 15 && NewWidth != 31)
1133 if (U == AddWithCst)
1151 I.getModule(), Intrinsic::sadd_with_overflow, NewType);
1159 Value *TruncA = Builder.CreateTrunc(
A, NewType,
A->getName() +
".trunc");
1160 Value *TruncB = Builder.CreateTrunc(
B, NewType,
B->getName() +
".trunc");
1161 CallInst *
Call = Builder.CreateCall(
F, {TruncA, TruncB},
"sadd");
1162 Value *
Add = Builder.CreateExtractValue(
Call, 0,
"sadd.result");
1180 if (!
I.isEquality())
1211 APInt(XBitWidth, XBitWidth - 1))))
1238 return new ICmpInst(Pred,
B, Cmp.getOperand(1));
1240 return new ICmpInst(Pred,
A, Cmp.getOperand(1));
1257 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1269 return new ICmpInst(Pred,
Y, Cmp.getOperand(1));
1275 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1278 if (BO0->hasNoUnsignedWrap() || BO0->hasNoSignedWrap()) {
1286 return new ICmpInst(Pred,
Y, Cmp.getOperand(1));
1291 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1307 return new ICmpInst(Pred, Stripped,
1320 const APInt *Mask, *Neg;
1336 auto *NewAnd =
Builder.CreateAnd(Num, *Mask);
1339 return new ICmpInst(Pred, NewAnd, Zero);
1360 Value *Op0 = Cmp.getOperand(0), *Op1 = Cmp.getOperand(1);
1376 for (
Value *V : Phi->incoming_values()) {
1384 PHINode *NewPhi =
Builder.CreatePHI(Cmp.getType(), Phi->getNumOperands());
1385 for (
auto [V, Pred] :
zip(
Ops, Phi->blocks()))
1400 Value *
X = Cmp.getOperand(0), *
Y = Cmp.getOperand(1);
1433 if (Cmp.isEquality() || (IsSignBit &&
hasBranchUse(Cmp)))
1438 if (Cmp.hasOneUse() &&
1452 if (!
match(BI->getCondition(),
1457 if (
DT.dominates(Edge0, Cmp.getParent())) {
1458 if (
auto *V = handleDomCond(DomPred, DomC))
1462 if (
DT.dominates(Edge1, Cmp.getParent()))
1478 Type *SrcTy =
X->getType();
1480 SrcBits = SrcTy->getScalarSizeInBits();
1484 if (shouldChangeType(Trunc->
getType(), SrcTy)) {
1486 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy,
C.sext(SrcBits)));
1488 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy,
C.zext(SrcBits)));
1491 if (
C.isOne() &&
C.getBitWidth() > 1) {
1496 ConstantInt::get(V->getType(), 1));
1508 auto NewPred = (Pred == Cmp.ICMP_EQ) ? Cmp.ICMP_UGE : Cmp.ICMP_ULT;
1510 ConstantInt::get(SrcTy, DstBits - Pow2->
logBase2()));
1516 Pred,
Y, ConstantInt::get(SrcTy,
C.logBase2() - Pow2->
logBase2()));
1522 if (!SrcTy->isVectorTy() && shouldChangeType(DstBits, SrcBits)) {
1526 Constant *WideC = ConstantInt::get(SrcTy,
C.zext(SrcBits));
1535 if ((
Known.Zero |
Known.One).countl_one() >= SrcBits - DstBits) {
1537 APInt NewRHS =
C.zext(SrcBits);
1539 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy, NewRHS));
1551 DstBits == SrcBits - ShAmt) {
1568 bool YIsSExt =
false;
1571 unsigned NoWrapFlags =
cast<TruncInst>(Cmp.getOperand(0))->getNoWrapKind() &
1573 if (Cmp.isSigned()) {
1584 if (
X->getType() !=
Y->getType() &&
1585 (!Cmp.getOperand(0)->hasOneUse() || !Cmp.getOperand(1)->hasOneUse()))
1587 if (!isDesirableIntType(
X->getType()->getScalarSizeInBits()) &&
1588 isDesirableIntType(
Y->getType()->getScalarSizeInBits())) {
1590 Pred = Cmp.getSwappedPredicate(Pred);
1595 else if (!Cmp.isSigned() &&
1609 Type *TruncTy = Cmp.getOperand(0)->getType();
1614 if (isDesirableIntType(TruncBits) &&
1615 !isDesirableIntType(
X->getType()->getScalarSizeInBits()))
1638 bool TrueIfSigned =
false;
1655 if (
Xor->hasOneUse()) {
1657 if (!Cmp.isEquality() && XorC->
isSignMask()) {
1658 Pred = Cmp.getFlippedSignednessPredicate();
1659 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(),
C ^ *XorC));
1664 Pred = Cmp.getFlippedSignednessPredicate();
1665 Pred = Cmp.getSwappedPredicate(Pred);
1666 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(),
C ^ *XorC));
1673 if (*XorC == ~
C && (
C + 1).isPowerOf2())
1676 if (*XorC ==
C && (
C + 1).isPowerOf2())
1681 if (*XorC == -
C &&
C.isPowerOf2())
1683 ConstantInt::get(
X->getType(), ~
C));
1685 if (*XorC ==
C && (-
C).isPowerOf2())
1687 ConstantInt::get(
X->getType(), ~
C));
1709 const APInt *ShiftC;
1714 Type *XType =
X->getType();
1720 return new ICmpInst(Pred,
Add, ConstantInt::get(XType, Bound));
1729 if (!Shift || !Shift->
isShift())
1737 unsigned ShiftOpcode = Shift->
getOpcode();
1738 bool IsShl = ShiftOpcode == Instruction::Shl;
1741 APInt NewAndCst, NewCmpCst;
1742 bool AnyCmpCstBitsShiftedOut;
1743 if (ShiftOpcode == Instruction::Shl) {
1751 NewCmpCst = C1.
lshr(*C3);
1752 NewAndCst = C2.
lshr(*C3);
1753 AnyCmpCstBitsShiftedOut = NewCmpCst.
shl(*C3) != C1;
1754 }
else if (ShiftOpcode == Instruction::LShr) {
1759 NewCmpCst = C1.
shl(*C3);
1760 NewAndCst = C2.
shl(*C3);
1761 AnyCmpCstBitsShiftedOut = NewCmpCst.
lshr(*C3) != C1;
1767 assert(ShiftOpcode == Instruction::AShr &&
"Unknown shift opcode");
1768 NewCmpCst = C1.
shl(*C3);
1769 NewAndCst = C2.
shl(*C3);
1770 AnyCmpCstBitsShiftedOut = NewCmpCst.
ashr(*C3) != C1;
1771 if (NewAndCst.
ashr(*C3) != C2)
1775 if (AnyCmpCstBitsShiftedOut) {
1785 Shift->
getOperand(0), ConstantInt::get(
And->getType(), NewAndCst));
1786 return new ICmpInst(Cmp.getPredicate(), NewAnd,
1787 ConstantInt::get(
And->getType(), NewCmpCst));
1804 return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
1818 return new TruncInst(
And->getOperand(0), Cmp.getType());
1829 ConstantInt::get(
X->getType(), ~*C2));
1834 ConstantInt::get(
X->getType(), -*C2));
1837 if (!
And->hasOneUse())
1840 if (Cmp.isEquality() && C1.
isZero()) {
1858 Constant *NegBOC = ConstantInt::get(
And->getType(), -NewC2);
1860 return new ICmpInst(NewPred,
X, NegBOC);
1878 if (!Cmp.getType()->isVectorTy()) {
1879 Type *WideType = W->getType();
1881 Constant *ZextC1 = ConstantInt::get(WideType, C1.
zext(WideScalarBits));
1882 Constant *ZextC2 = ConstantInt::get(WideType, C2->
zext(WideScalarBits));
1884 return new ICmpInst(Cmp.getPredicate(), NewAnd, ZextC1);
1895 if (!Cmp.isSigned() && C1.
isZero() &&
And->getOperand(0)->hasOneUse() &&
1902 unsigned UsesRemoved = 0;
1903 if (
And->hasOneUse())
1905 if (
Or->hasOneUse())
1912 if (UsesRemoved >= RequireUsesRemoved) {
1916 One,
Or->getName());
1918 return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
1932 if (!Cmp.getParent()->getParent()->hasFnAttribute(
1933 Attribute::NoImplicitFloat) &&
1936 Type *FPType = V->getType()->getScalarType();
1937 if (FPType->isIEEELikeFPTy() && (C1.
isZero() || C1 == *C2)) {
1938 APInt ExponentMask =
1940 if (*C2 == ExponentMask) {
1941 unsigned Mask = C1.
isZero()
1975 Constant *MinSignedC = ConstantInt::get(
1979 return new ICmpInst(NewPred,
X, MinSignedC);
1994 if (!Cmp.isEquality())
2004 if (
C.getBitWidth() > 1 && (
C.isZero() ||
C.isOne()) &&
2008 return new ICmpInst(Pred, MatchedX, Cmp.getOperand(1));
2012 return new TruncInst(MatchedX, Cmp.getType());
2016 if (
And->hasOneUse()) {
2017 Value *Trunc =
Builder.CreateTrunc(MatchedX, Cmp.getType());
2025 if (Cmp.getOperand(1) ==
Y &&
C.isNegatedPowerOf2()) {
2036 X->getType()->isIntOrIntVectorTy(1) && (
C.isZero() ||
C.isOne())) {
2042 return BinaryOperator::CreateAnd(TruncY,
X);
2060 const APInt *Addend, *Msk;
2064 APInt NewComperand = (
C - *Addend) & *Msk;
2065 Value *MaskA =
Builder.CreateAnd(
A, ConstantInt::get(
A->getType(), *Msk));
2067 ConstantInt::get(MaskA->
getType(), NewComperand));
2089 while (!WorkList.
empty()) {
2090 auto MatchOrOperatorArgument = [&](
Value *OrOperatorArgument) {
2093 if (
match(OrOperatorArgument,
2099 if (
match(OrOperatorArgument,
2109 Value *OrOperatorLhs, *OrOperatorRhs;
2111 if (!
match(CurrentValue,
2116 MatchOrOperatorArgument(OrOperatorRhs);
2117 MatchOrOperatorArgument(OrOperatorLhs);
2122 Value *LhsCmp = Builder.CreateICmp(Pred, CmpValues.
rbegin()->first,
2123 CmpValues.
rbegin()->second);
2125 for (
auto It = CmpValues.
rbegin() + 1; It != CmpValues.
rend(); ++It) {
2126 Value *RhsCmp = Builder.CreateICmp(Pred, It->first, It->second);
2127 LhsCmp = Builder.CreateBinOp(BOpc, LhsCmp, RhsCmp);
2143 ConstantInt::get(V->getType(), 1));
2146 Value *OrOp0 =
Or->getOperand(0), *OrOp1 =
Or->getOperand(1);
2153 Builder.CreateXor(OrOp1, ConstantInt::get(OrOp1->getType(),
C));
2154 return new ICmpInst(Pred, OrOp0, NewC);
2158 if (
match(OrOp1,
m_APInt(MaskC)) && Cmp.isEquality()) {
2159 if (*MaskC ==
C && (
C + 1).isPowerOf2()) {
2164 return new ICmpInst(Pred, OrOp0, OrOp1);
2171 if (
Or->hasOneUse()) {
2173 Constant *NewC = ConstantInt::get(
Or->getType(),
C ^ (*MaskC));
2185 Constant *NewC = ConstantInt::get(
X->getType(), TrueIfSigned ? 1 : 0);
2213 if (!Cmp.isEquality() || !
C.isZero() || !
Or->hasOneUse())
2244 if (
X ==
Mul->getOperand(1) && !Cmp.isSigned()) {
2246 bool IsSqr =
C == R * R;
2249 if (Cmp.isEquality() &&
2250 (
Mul->hasNoUnsignedWrap() || (
Mul->hasNoSignedWrap() &&
C.isZero()))) {
2258 return new ICmpInst(Pred,
X, ConstantInt::get(MulTy, R));
2263 if (
Mul->hasNoUnsignedWrap()) {
2266 return new ICmpInst(Pred,
X, ConstantInt::get(MulTy, R));
2280 return new ICmpInst(Cmp.getStrictPredicate(),
X,
2281 ConstantInt::get(MulTy, R));
2304 if (Cmp.isEquality()) {
2306 if (
Mul->hasNoSignedWrap() &&
C.srem(*MulC).isZero()) {
2307 Constant *NewC = ConstantInt::get(MulTy,
C.sdiv(*MulC));
2315 if (
C.urem(*MulC).isZero()) {
2318 if ((*MulC & 1).isOne() ||
Mul->hasNoUnsignedWrap()) {
2319 Constant *NewC = ConstantInt::get(MulTy,
C.udiv(*MulC));
2332 if (
C.isMinSignedValue() && MulC->
isAllOnes())
2338 NewC = ConstantInt::get(
2342 "Unexpected predicate");
2343 NewC = ConstantInt::get(
2348 NewC = ConstantInt::get(
2352 "Unexpected predicate");
2353 NewC = ConstantInt::get(
2358 return NewC ?
new ICmpInst(Pred,
X, NewC) :
nullptr;
2370 unsigned TypeBits =
C.getBitWidth();
2372 if (Cmp.isUnsigned()) {
2392 return new ICmpInst(Pred,
Y, ConstantInt::get(ShiftType, CLog2));
2393 }
else if (Cmp.isSigned() && C2->
isOne()) {
2394 Constant *BitWidthMinusOne = ConstantInt::get(ShiftType, TypeBits - 1);
2415 const APInt *ShiftVal;
2445 const APInt *ShiftAmt;
2451 unsigned TypeBits =
C.getBitWidth();
2452 if (ShiftAmt->
uge(TypeBits))
2464 APInt ShiftedC =
C.ashr(*ShiftAmt);
2465 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2468 C.ashr(*ShiftAmt).shl(*ShiftAmt) ==
C) {
2469 APInt ShiftedC =
C.ashr(*ShiftAmt);
2470 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2477 assert(!
C.isMinSignedValue() &&
"Unexpected icmp slt");
2478 APInt ShiftedC = (
C - 1).ashr(*ShiftAmt) + 1;
2479 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2489 APInt ShiftedC =
C.lshr(*ShiftAmt);
2490 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2493 C.lshr(*ShiftAmt).shl(*ShiftAmt) ==
C) {
2494 APInt ShiftedC =
C.lshr(*ShiftAmt);
2495 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2502 assert(
C.ugt(0) &&
"ult 0 should have been eliminated");
2503 APInt ShiftedC = (
C - 1).lshr(*ShiftAmt) + 1;
2504 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2508 if (Cmp.isEquality() && Shl->
hasOneUse()) {
2514 Constant *LShrC = ConstantInt::get(ShType,
C.lshr(*ShiftAmt));
2519 bool TrueIfSigned =
false;
2531 if (Cmp.isUnsigned() && Shl->
hasOneUse()) {
2533 if ((
C + 1).isPowerOf2() &&
2541 if (
C.isPowerOf2() &&
2571 Pred, ConstantInt::get(ShType->
getContext(),
C))) {
2572 CmpPred = FlippedStrictness->first;
2580 ConstantInt::get(TruncTy, RHSC.
ashr(*ShiftAmt).
trunc(TypeBits - Amt));
2582 Builder.CreateTrunc(
X, TruncTy,
"",
false,
2599 if (Cmp.isEquality() && Shr->
isExact() &&
C.isZero())
2600 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
2602 bool IsAShr = Shr->
getOpcode() == Instruction::AShr;
2603 const APInt *ShiftValC;
2605 if (Cmp.isEquality())
2623 assert(ShiftValC->
uge(
C) &&
"Expected simplify of compare");
2624 assert((IsUGT || !
C.isZero()) &&
"Expected X u< 0 to simplify");
2626 unsigned CmpLZ = IsUGT ?
C.countl_zero() : (
C - 1).
countl_zero();
2634 const APInt *ShiftAmtC;
2640 unsigned TypeBits =
C.getBitWidth();
2642 if (ShAmtVal >= TypeBits || ShAmtVal == 0)
2645 bool IsExact = Shr->
isExact();
2653 (
C - 1).isPowerOf2() &&
C.countLeadingZeros() > ShAmtVal) {
2659 APInt ShiftedC = (
C - 1).shl(ShAmtVal) + 1;
2660 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2666 APInt ShiftedC =
C.shl(ShAmtVal);
2667 if (ShiftedC.
ashr(ShAmtVal) ==
C)
2668 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2672 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2673 if (!
C.isMaxSignedValue() && !(
C + 1).shl(ShAmtVal).isMinSignedValue() &&
2674 (ShiftedC + 1).ashr(ShAmtVal) == (
C + 1))
2675 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2681 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2682 if ((ShiftedC + 1).ashr(ShAmtVal) == (
C + 1) ||
2683 (
C + 1).shl(ShAmtVal).isMinSignedValue())
2684 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2691 if (
C.getBitWidth() > 2 &&
C.getNumSignBits() <= ShAmtVal) {
2701 }
else if (!IsAShr) {
2705 APInt ShiftedC =
C.shl(ShAmtVal);
2706 if (ShiftedC.
lshr(ShAmtVal) ==
C)
2707 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2711 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2712 if ((ShiftedC + 1).lshr(ShAmtVal) == (
C + 1))
2713 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2717 if (!Cmp.isEquality())
2725 assert(((IsAShr &&
C.shl(ShAmtVal).ashr(ShAmtVal) ==
C) ||
2726 (!IsAShr &&
C.shl(ShAmtVal).lshr(ShAmtVal) ==
C)) &&
2727 "Expected icmp+shr simplify did not occur.");
2732 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy,
C << ShAmtVal));
2738 Constant *Mask = ConstantInt::get(ShrTy, Val);
2740 return new ICmpInst(Pred,
And, ConstantInt::get(ShrTy,
C << ShAmtVal));
2757 const APInt *DivisorC;
2766 "ult X, 0 should have been simplified already.");
2771 if (!NormalizedC.
uge(DivisorC->
abs() - 1))
2794 const APInt *DivisorC;
2803 !
C.isStrictlyPositive()))
2809 Constant *MaskC = ConstantInt::get(Ty, SignMask | (*DivisorC - 1));
2813 return new ICmpInst(Pred,
And, ConstantInt::get(Ty,
C));
2840 assert(*C2 != 0 &&
"udiv 0, X should have been simplified already.");
2845 "icmp ugt X, UINT_MAX should have been simplified already.");
2847 ConstantInt::get(Ty, C2->
udiv(
C + 1)));
2852 assert(
C != 0 &&
"icmp ult X, 0 should have been simplified already.");
2854 ConstantInt::get(Ty, C2->
udiv(
C)));
2868 bool DivIsSigned = Div->
getOpcode() == Instruction::SDiv;
2878 if (Cmp.isEquality() && Div->
hasOneUse() &&
C.isSignBitSet() &&
2879 (!DivIsSigned ||
C.isMinSignedValue())) {
2880 Value *XBig =
Builder.CreateICmp(Pred,
X, ConstantInt::get(Ty,
C));
2881 Value *YOne =
Builder.CreateICmp(Pred,
Y, ConstantInt::get(Ty, 1));
2907 if (!Cmp.isEquality() && DivIsSigned != Cmp.isSigned()) {
2911 DivIsSigned =
false;
2930 bool ProdOV = (DivIsSigned ? Prod.
sdiv(*C2) : Prod.
udiv(*C2)) !=
C;
2943 int LoOverflow = 0, HiOverflow = 0;
2944 APInt LoBound, HiBound;
2949 HiOverflow = LoOverflow = ProdOV;
2958 LoBound = -(RangeSize - 1);
2959 HiBound = RangeSize;
2960 }
else if (
C.isStrictlyPositive()) {
2962 HiOverflow = LoOverflow = ProdOV;
2968 LoOverflow = HiOverflow = ProdOV ? -1 : 0;
2970 APInt DivNeg = -RangeSize;
2971 LoOverflow =
addWithOverflow(LoBound, HiBound, DivNeg,
true) ? -1 : 0;
2979 LoBound = RangeSize + 1;
2980 HiBound = -RangeSize;
2981 if (HiBound == *C2) {
2985 }
else if (
C.isStrictlyPositive()) {
2988 HiOverflow = LoOverflow = ProdOV ? -1 : 0;
2994 LoOverflow = HiOverflow = ProdOV;
3007 if (LoOverflow && HiOverflow)
3011 X, ConstantInt::get(Ty, LoBound));
3014 X, ConstantInt::get(Ty, HiBound));
3018 if (LoOverflow && HiOverflow)
3022 X, ConstantInt::get(Ty, LoBound));
3025 X, ConstantInt::get(Ty, HiBound));
3030 if (LoOverflow == +1)
3032 if (LoOverflow == -1)
3034 return new ICmpInst(Pred,
X, ConstantInt::get(Ty, LoBound));
3037 if (HiOverflow == +1)
3039 if (HiOverflow == -1)
3081 bool HasNSW =
Sub->hasNoSignedWrap();
3082 bool HasNUW =
Sub->hasNoUnsignedWrap();
3084 ((Cmp.isUnsigned() && HasNUW) || (Cmp.isSigned() && HasNSW)) &&
3086 return new ICmpInst(SwappedPred,
Y, ConstantInt::get(Ty, SubResult));
3094 if (Cmp.isEquality() &&
C.isZero() &&
3095 none_of((
Sub->users()), [](
const User *U) { return isa<PHINode>(U); }))
3103 if (!
Sub->hasOneUse())
3106 if (
Sub->hasNoSignedWrap()) {
3130 (*C2 & (
C - 1)) == (
C - 1))
3143 return new ICmpInst(SwappedPred,
Add, ConstantInt::get(Ty, ~
C));
3149 auto FoldConstant = [&](
bool Val) {
3150 Constant *Res = Val ? Builder.getTrue() : Builder.getFalse();
3157 switch (
Table.to_ulong()) {
3159 return FoldConstant(
false);
3161 return HasOneUse ? Builder.CreateNot(Builder.CreateOr(Op0, Op1)) :
nullptr;
3163 return HasOneUse ? Builder.CreateAnd(Builder.CreateNot(Op0), Op1) :
nullptr;
3165 return Builder.CreateNot(Op0);
3167 return HasOneUse ? Builder.CreateAnd(Op0, Builder.CreateNot(Op1)) :
nullptr;
3169 return Builder.CreateNot(Op1);
3171 return Builder.CreateXor(Op0, Op1);
3173 return HasOneUse ? Builder.CreateNot(Builder.CreateAnd(Op0, Op1)) :
nullptr;
3175 return Builder.CreateAnd(Op0, Op1);
3177 return HasOneUse ? Builder.CreateNot(Builder.CreateXor(Op0, Op1)) :
nullptr;
3181 return HasOneUse ? Builder.CreateOr(Builder.CreateNot(Op0), Op1) :
nullptr;
3185 return HasOneUse ? Builder.CreateOr(Op0, Builder.CreateNot(Op1)) :
nullptr;
3187 return Builder.CreateOr(Op0, Op1);
3189 return FoldConstant(
true);
3204 Cmp.getType() !=
A->getType() || Cmp.getType() !=
B->getType())
3207 std::bitset<4>
Table;
3208 auto ComputeTable = [&](
bool First,
bool Second) -> std::optional<bool> {
3212 auto *Val = Res->getType()->isVectorTy() ? Res->getSplatValue() : Res;
3216 return std::nullopt;
3219 for (
unsigned I = 0;
I < 4; ++
I) {
3220 bool First = (
I >> 1) & 1;
3221 bool Second =
I & 1;
3222 if (
auto Res = ComputeTable(
First, Second))
3244 const APInt *ShAmtC;
3252 return new ICmpInst(Pred,
A, ConstantInt::get(
A->getType(),
C));
3264 if (
Add->hasNoUnsignedWrap() &&
3267 APInt NewC =
C.usub_ov(*C2, Overflow);
3271 return new ICmpInst(Pred,
X, ConstantInt::get(Ty, NewC));
3276 if (
Add->hasNoSignedWrap() &&
3279 APInt NewC =
C.ssub_ov(*C2, Overflow);
3283 return new ICmpInst(ChosenPred,
X, ConstantInt::get(Ty, NewC));
3287 C.isNonNegative() && (
C - *C2).isNonNegative() &&
3290 .isAllNonNegative())
3292 ConstantInt::get(Ty,
C - *C2));
3297 if (Cmp.isSigned()) {
3298 if (
Lower.isSignMask())
3300 if (
Upper.isSignMask())
3303 if (
Lower.isMinValue())
3305 if (
Upper.isMinValue())
3338 if (!
Add->hasOneUse())
3353 ConstantInt::get(Ty,
C * 2));
3367 Builder.CreateAdd(
X, ConstantInt::get(Ty, *C2 -
C - 1)),
3368 ConstantInt::get(Ty, ~
C));
3373 Type *NewCmpTy = V->getType();
3375 if (shouldChangeType(Ty, NewCmpTy)) {
3386 :
Builder.CreateAdd(V, ConstantInt::get(NewCmpTy, EquivOffset)),
3387 ConstantInt::get(NewCmpTy, EquivInt));
3409 Value *EqualVal =
SI->getTrueValue();
3410 Value *UnequalVal =
SI->getFalseValue();
3433 auto FlippedStrictness =
3435 if (!FlippedStrictness)
3438 "basic correctness failure");
3439 RHS2 = FlippedStrictness->second;
3451 assert(
C &&
"Cmp RHS should be a constant int!");
3457 Value *OrigLHS, *OrigRHS;
3458 ConstantInt *C1LessThan, *C2Equal, *C3GreaterThan;
3459 if (Cmp.hasOneUse() &&
3462 assert(C1LessThan && C2Equal && C3GreaterThan);
3465 C1LessThan->
getValue(),
C->getValue(), Cmp.getPredicate());
3467 Cmp.getPredicate());
3469 C3GreaterThan->
getValue(),
C->getValue(), Cmp.getPredicate());
3480 if (TrueWhenLessThan)
3486 if (TrueWhenGreaterThan)
3501 Value *Op1 = Cmp.getOperand(1);
3502 Value *BCSrcOp = Bitcast->getOperand(0);
3503 Type *SrcType = Bitcast->getSrcTy();
3504 Type *DstType = Bitcast->getType();
3508 if (SrcType->isVectorTy() == DstType->isVectorTy() &&
3509 SrcType->getScalarSizeInBits() == DstType->getScalarSizeInBits()) {
3524 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(), 1));
3551 Type *XType =
X->getType();
3554 if (!(XType->
isPPC_FP128Ty() || SrcType->isPPC_FP128Ty())) {
3569 Type *FPType = SrcType->getScalarType();
3570 if (!Cmp.getParent()->getParent()->hasFnAttribute(
3571 Attribute::NoImplicitFloat) &&
3572 Cmp.isEquality() && FPType->isIEEELikeFPTy()) {
3578 Builder.createIsFPClass(BCSrcOp, Mask));
3585 if (!
match(Cmp.getOperand(1),
m_APInt(
C)) || !DstType->isIntegerTy() ||
3586 !SrcType->isIntOrIntVectorTy())
3596 if (Cmp.isEquality() &&
C->isAllOnes() && Bitcast->hasOneUse()) {
3597 if (
Value *NotBCSrcOp =
3599 Value *Cast =
Builder.CreateBitCast(NotBCSrcOp, DstType);
3608 if (Cmp.isEquality() &&
C->isZero() && Bitcast->hasOneUse() &&
3611 Type *NewType =
Builder.getIntNTy(VecTy->getPrimitiveSizeInBits());
3631 if (
C->isSplat(EltTy->getBitWidth())) {
3637 Value *Extract =
Builder.CreateExtractElement(Vec, Mask[0]);
3638 Value *NewC = ConstantInt::get(EltTy,
C->trunc(EltTy->getBitWidth()));
3639 return new ICmpInst(Pred, Extract, NewC);
3677 if (
match(Cmp.getOperand(0),
3683 bool ValidPred =
true;
3701 X->getType()->getScalarType()->getFltSemantics();
3704 if (!Exp.isNegative() && Exp.sle(MaxExp + 1) &&
3706 int ExpVal =
static_cast<int>(Exp.getSExtValue());
3711 ConstantFP::get(
X->getType(), CmpConst));
3720 Value *Cmp0 = Cmp.getOperand(0);
3722 if (
C->isZero() && Cmp.isEquality() && Cmp0->
hasOneUse() &&
3729 return new ICmpInst(Cmp.getPredicate(),
X,
Y);
3744 if (!Cmp.isEquality())
3753 case Instruction::SRem:
3764 case Instruction::Add: {
3771 }
else if (
C.isZero()) {
3774 if (
Value *NegVal = dyn_castNegVal(BOp1))
3775 return new ICmpInst(Pred, BOp0, NegVal);
3776 if (
Value *NegVal = dyn_castNegVal(BOp0))
3777 return new ICmpInst(Pred, NegVal, BOp1);
3786 return new ICmpInst(Pred, BOp0, Neg);
3791 case Instruction::Xor:
3796 }
else if (
C.isZero()) {
3798 return new ICmpInst(Pred, BOp0, BOp1);
3801 case Instruction::Or: {
3822 Cond->getType() == Cmp.getType()) {
3860 case Instruction::UDiv:
3861 case Instruction::SDiv:
3871 return new ICmpInst(Pred, BOp0, BOp1);
3874 Instruction::Mul, BO->
getOpcode() == Instruction::SDiv, BOp1,
3875 Cmp.getOperand(1), BO);
3879 return new ICmpInst(Pred, YC, BOp0);
3883 if (BO->
getOpcode() == Instruction::UDiv &&
C.isZero()) {
3886 return new ICmpInst(NewPred, BOp1, BOp0);
3900 "Non-ctpop intrin in ctpop fold");
3935 Type *Ty =
II->getType();
3939 switch (
II->getIntrinsicID()) {
3940 case Intrinsic::abs:
3943 if (
C.isZero() ||
C.isMinSignedValue())
3944 return new ICmpInst(Pred,
II->getArgOperand(0), ConstantInt::get(Ty,
C));
3947 case Intrinsic::bswap:
3949 return new ICmpInst(Pred,
II->getArgOperand(0),
3950 ConstantInt::get(Ty,
C.byteSwap()));
3952 case Intrinsic::bitreverse:
3954 return new ICmpInst(Pred,
II->getArgOperand(0),
3955 ConstantInt::get(Ty,
C.reverseBits()));
3957 case Intrinsic::ctlz:
3958 case Intrinsic::cttz: {
3961 return new ICmpInst(Pred,
II->getArgOperand(0),
3967 unsigned Num =
C.getLimitedValue(
BitWidth);
3969 bool IsTrailing =
II->getIntrinsicID() == Intrinsic::cttz;
3972 APInt Mask2 = IsTrailing
3976 ConstantInt::get(Ty, Mask2));
3981 case Intrinsic::ctpop: {
3984 bool IsZero =
C.isZero();
3986 return new ICmpInst(Pred,
II->getArgOperand(0),
3993 case Intrinsic::fshl:
3994 case Intrinsic::fshr:
3995 if (
II->getArgOperand(0) ==
II->getArgOperand(1)) {
3996 const APInt *RotAmtC;
4000 return new ICmpInst(Pred,
II->getArgOperand(0),
4001 II->getIntrinsicID() == Intrinsic::fshl
4002 ? ConstantInt::get(Ty,
C.rotr(*RotAmtC))
4003 : ConstantInt::get(Ty,
C.rotl(*RotAmtC)));
4007 case Intrinsic::umax:
4008 case Intrinsic::uadd_sat: {
4011 if (
C.isZero() &&
II->hasOneUse()) {
4018 case Intrinsic::ssub_sat:
4023 if (
C.isZero() &&
II->getType()->getScalarSizeInBits() > 1)
4024 return new ICmpInst(Pred,
II->getArgOperand(0),
II->getArgOperand(1));
4026 case Intrinsic::usub_sat: {
4031 return new ICmpInst(NewPred,
II->getArgOperand(0),
II->getArgOperand(1));
4046 assert(Cmp.isEquality());
4049 Value *Op0 = Cmp.getOperand(0);
4050 Value *Op1 = Cmp.getOperand(1);
4053 if (!IIOp0 || !IIOp1 || IIOp0->getIntrinsicID() != IIOp1->getIntrinsicID())
4056 switch (IIOp0->getIntrinsicID()) {
4057 case Intrinsic::bswap:
4058 case Intrinsic::bitreverse:
4061 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
4062 case Intrinsic::fshl:
4063 case Intrinsic::fshr: {
4066 if (IIOp0->getOperand(0) != IIOp0->getOperand(1))
4068 if (IIOp1->getOperand(0) != IIOp1->getOperand(1))
4070 if (IIOp0->getOperand(2) == IIOp1->getOperand(2))
4071 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
4077 unsigned OneUses = IIOp0->hasOneUse() + IIOp1->hasOneUse();
4082 Builder.CreateSub(IIOp0->getOperand(2), IIOp1->getOperand(2));
4083 Value *CombinedRotate = Builder.CreateIntrinsic(
4084 Op0->
getType(), IIOp0->getIntrinsicID(),
4085 {IIOp0->getOperand(0), IIOp0->getOperand(0), SubAmt});
4086 return new ICmpInst(Pred, IIOp1->getOperand(0), CombinedRotate);
4104 switch (
II->getIntrinsicID()) {
4107 case Intrinsic::fshl:
4108 case Intrinsic::fshr:
4109 if (Cmp.isEquality() &&
II->getArgOperand(0) ==
II->getArgOperand(1)) {
4111 if (
C.isZero() ||
C.isAllOnes())
4112 return new ICmpInst(Pred,
II->getArgOperand(0), Cmp.getOperand(1));
4126 case Instruction::Xor:
4130 case Instruction::And:
4134 case Instruction::Or:
4138 case Instruction::Mul:
4142 case Instruction::Shl:
4146 case Instruction::LShr:
4147 case Instruction::AShr:
4151 case Instruction::SRem:
4155 case Instruction::UDiv:
4159 case Instruction::SDiv:
4163 case Instruction::Sub:
4167 case Instruction::Add:
4191 if (!
II->hasOneUse())
4207 Value *Op0 =
II->getOperand(0);
4208 Value *Op1 =
II->getOperand(1);
4217 switch (
II->getIntrinsicID()) {
4220 "This function only works with usub_sat and uadd_sat for now!");
4221 case Intrinsic::uadd_sat:
4224 case Intrinsic::usub_sat:
4234 II->getBinaryOp(), *COp1,
II->getNoWrapKind());
4241 if (
II->getBinaryOp() == Instruction::Add)
4247 SatValCheck ? Instruction::BinaryOps::Or : Instruction::BinaryOps::And;
4249 std::optional<ConstantRange> Combination;
4250 if (CombiningOp == Instruction::BinaryOps::Or)
4262 Combination->getEquivalentICmp(EquivPred, EquivInt, EquivOffset);
4266 Builder.CreateAdd(Op0, ConstantInt::get(Op1->
getType(), EquivOffset)),
4267 ConstantInt::get(Op1->
getType(), EquivInt));
4274 std::optional<ICmpInst::Predicate> NewPredicate = std::nullopt;
4279 NewPredicate = Pred;
4283 else if (
C.isAllOnes())
4291 else if (
C.isZero())
4308 if (!
C.isZero() && !
C.isAllOnes())
4319 if (
I->getIntrinsicID() == Intrinsic::scmp)
4333 switch (
II->getIntrinsicID()) {
4336 case Intrinsic::uadd_sat:
4337 case Intrinsic::usub_sat:
4342 case Intrinsic::ctpop: {
4347 case Intrinsic::scmp:
4348 case Intrinsic::ucmp:
4354 if (Cmp.isEquality())
4357 Type *Ty =
II->getType();
4359 switch (
II->getIntrinsicID()) {
4360 case Intrinsic::ctpop: {
4372 case Intrinsic::ctlz: {
4375 unsigned Num =
C.getLimitedValue();
4378 II->getArgOperand(0), ConstantInt::get(Ty, Limit));
4383 unsigned Num =
C.getLimitedValue();
4386 II->getArgOperand(0), ConstantInt::get(Ty, Limit));
4390 case Intrinsic::cttz: {
4392 if (!
II->hasOneUse())
4399 Builder.CreateAnd(
II->getArgOperand(0), Mask),
4407 Builder.CreateAnd(
II->getArgOperand(0), Mask),
4412 case Intrinsic::ssub_sat:
4419 return new ICmpInst(Pred,
II->getArgOperand(0),
II->getArgOperand(1));
4423 II->getArgOperand(1));
4427 II->getArgOperand(1));
4430 case Intrinsic::abs: {
4431 if (!
II->hasOneUse())
4435 bool IsIntMinPoison =
4442 Builder.CreateAdd(
X, ConstantInt::get(Ty,
C)),
4443 ConstantInt::get(Ty, 2 *
C));
4450 Builder.CreateAdd(
X, ConstantInt::get(Ty,
C - 1)),
4451 ConstantInt::get(Ty, 2 * (
C - 1)));
4465 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
4472 case Instruction::IntToPtr:
4477 APInt NullPtrValue =
4485 case Instruction::Load:
4502 auto SimplifyOp = [&](
Value *
Op,
bool SelectCondIsTrue) ->
Value * {
4506 SI->getCondition(), Pred,
Op, RHS,
DL, SelectCondIsTrue))
4507 return ConstantInt::get(
I.getType(), *Impl);
4512 Value *Op1 = SimplifyOp(
SI->getOperand(1),
true);
4516 Value *Op2 = SimplifyOp(
SI->getOperand(2),
false);
4520 auto Simplifies = [&](
Value *
Op,
unsigned Idx) {
4535 bool Transform =
false;
4538 else if (Simplifies(Op1, 1) || Simplifies(Op2, 2)) {
4540 if (
SI->hasOneUse())
4543 else if (CI && !CI->
isZero())
4551 Op1 =
Builder.CreateICmp(Pred,
SI->getOperand(1), RHS,
I.getName());
4553 Op2 =
Builder.CreateICmp(Pred,
SI->getOperand(2), RHS,
I.getName());
4563 unsigned Depth = 0) {
4566 if (V->getType()->getScalarSizeInBits() == 1)
4574 switch (
I->getOpcode()) {
4575 case Instruction::ZExt:
4578 case Instruction::SExt:
4582 case Instruction::And:
4583 case Instruction::Or:
4590 case Instruction::Xor:
4600 case Instruction::Select:
4604 case Instruction::Shl:
4607 case Instruction::LShr:
4610 case Instruction::AShr:
4614 case Instruction::Add:
4620 case Instruction::Sub:
4626 case Instruction::Call: {
4628 switch (
II->getIntrinsicID()) {
4631 case Intrinsic::umax:
4632 case Intrinsic::smax:
4633 case Intrinsic::umin:
4634 case Intrinsic::smin:
4639 case Intrinsic::bitreverse:
4729 auto IsLowBitMask = [&]() {
4747 auto Check = [&]() {
4765 auto Check = [&]() {
4784 if (!IsLowBitMask())
4803 const APInt *C0, *C1;
4820 const APInt &MaskedBits = *C0;
4821 assert(MaskedBits != 0 &&
"shift by zero should be folded away already.");
4842 auto *XType =
X->getType();
4843 const unsigned XBitWidth = XType->getScalarSizeInBits();
4845 assert(
BitWidth.ugt(MaskedBits) &&
"shifts should leave some bits untouched");
4858 Value *T0 = Builder.CreateAdd(
X, ConstantInt::get(XType, AddCst));
4860 Value *
T1 = Builder.CreateICmp(DstPred, T0, ConstantInt::get(XType, ICmpCst));
4876 !
I.getOperand(0)->hasOneUse())
4901 assert(NarrowestTy ==
I.getOperand(0)->getType() &&
4902 "We did not look past any shifts while matching XShift though.");
4903 bool HadTrunc = WidestTy !=
I.getOperand(0)->getType();
4910 auto XShiftOpcode = XShift->
getOpcode();
4911 if (XShiftOpcode == YShift->
getOpcode())
4914 Value *
X, *XShAmt, *
Y, *YShAmt;
4923 if (!
match(
I.getOperand(0),
4949 unsigned MaximalPossibleTotalShiftAmount =
4952 APInt MaximalRepresentableShiftAmount =
4954 if (MaximalRepresentableShiftAmount.
ult(MaximalPossibleTotalShiftAmount))
4963 if (NewShAmt->getType() != WidestTy) {
4973 if (!
match(NewShAmt,
4975 APInt(WidestBitWidth, WidestBitWidth))))
4980 auto CanFold = [NewShAmt, WidestBitWidth, NarrowestShift, SQ,
4986 ? NewShAmt->getSplatValue()
4989 if (NewShAmtSplat &&
4997 unsigned MinLeadZero =
Known.countMinLeadingZeros();
4999 unsigned MaxActiveBits =
Known.getBitWidth() - MinLeadZero;
5000 if (MaxActiveBits <= 1)
5008 unsigned MinLeadZero =
Known.countMinLeadingZeros();
5010 unsigned MaxActiveBits =
Known.getBitWidth() - MinLeadZero;
5011 if (MaxActiveBits <= 1)
5014 if (NewShAmtSplat) {
5017 if (AdjNewShAmt.
ule(MinLeadZero))
5028 X = Builder.CreateZExt(
X, WidestTy);
5029 Y = Builder.CreateZExt(
Y, WidestTy);
5031 Value *T0 = XShiftOpcode == Instruction::BinaryOps::LShr
5032 ? Builder.CreateLShr(
X, NewShAmt)
5033 : Builder.CreateShl(
X, NewShAmt);
5034 Value *
T1 = Builder.CreateAnd(T0,
Y);
5035 return Builder.CreateICmp(
I.getPredicate(),
T1,
5053 if (!
I.isEquality() &&
5063 NeedNegation =
false;
5066 NeedNegation =
true;
5072 if (
I.isEquality() &&
5087 bool MulHadOtherUses =
Mul && !
Mul->hasOneUse();
5088 if (MulHadOtherUses)
5092 Div->
getOpcode() == Instruction::UDiv ? Intrinsic::umul_with_overflow
5093 : Intrinsic::smul_with_overflow,
5094 X->getType(), {X, Y},
nullptr,
"mul");
5099 if (MulHadOtherUses)
5104 Res =
Builder.CreateNot(Res,
"mul.not.ov");
5108 if (MulHadOtherUses)
5134 Type *Ty =
X->getType();
5138 Value *
And = Builder.CreateAnd(
X, MaxSignedVal);
5148 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5210 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5245 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5261 return new ICmpInst(PredOut, Op0, Op1);
5281 return new ICmpInst(NewPred, Op0, Const);
5293 if (!
C.isPowerOf2())
5306 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5374 return new ICmpInst(NewPred, Op1, Zero);
5383 return new ICmpInst(NewPred, Op0, Zero);
5387 bool NoOp0WrapProblem =
false, NoOp1WrapProblem =
false;
5388 bool Op0HasNUW =
false, Op1HasNUW =
false;
5389 bool Op0HasNSW =
false, Op1HasNSW =
false;
5393 bool &HasNSW,
bool &HasNUW) ->
bool {
5400 }
else if (BO.
getOpcode() == Instruction::Or) {
5408 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr;
5412 NoOp0WrapProblem = hasNoWrapProblem(*BO0, Pred, Op0HasNSW, Op0HasNUW);
5416 NoOp1WrapProblem = hasNoWrapProblem(*BO1, Pred, Op1HasNSW, Op1HasNUW);
5421 if ((
A == Op1 ||
B == Op1) && NoOp0WrapProblem)
5427 if ((
C == Op0 ||
D == Op0) && NoOp1WrapProblem)
5432 if (
A &&
C && (
A ==
C ||
A ==
D ||
B ==
C ||
B ==
D) && NoOp0WrapProblem &&
5440 }
else if (
A ==
D) {
5444 }
else if (
B ==
C) {
5461 bool IsNegative) ->
bool {
5462 const APInt *OffsetC;
5474 if (!
C.isStrictlyPositive())
5495 if (
A && NoOp0WrapProblem &&
5496 ShareCommonDivisor(
A, Op1,
B,
5507 if (
C && NoOp1WrapProblem &&
5508 ShareCommonDivisor(Op0,
C,
D,
5521 if (
A &&
C && NoOp0WrapProblem && NoOp1WrapProblem &&
5523 const APInt *AP1, *AP2;
5531 if (AP1Abs.
uge(AP2Abs)) {
5532 APInt Diff = *AP1 - *AP2;
5535 A, C3,
"", Op0HasNUW && Diff.
ule(*AP1), Op0HasNSW);
5538 APInt Diff = *AP2 - *AP1;
5541 C, C3,
"", Op1HasNUW && Diff.
ule(*AP2), Op1HasNSW);
5560 if (BO0 && BO0->
getOpcode() == Instruction::Sub) {
5564 if (BO1 && BO1->
getOpcode() == Instruction::Sub) {
5570 if (
A == Op1 && NoOp0WrapProblem)
5573 if (
C == Op0 && NoOp1WrapProblem)
5593 if (
B &&
D &&
B ==
D && NoOp0WrapProblem && NoOp1WrapProblem)
5597 if (
A &&
C &&
A ==
C && NoOp0WrapProblem && NoOp1WrapProblem)
5605 if (RHSC->isNotMinSignedValue())
5606 return new ICmpInst(
I.getSwappedPredicate(),
X,
5624 if (Op0HasNSW && Op1HasNSW) {
5631 SQ.getWithInstruction(&
I));
5636 SQ.getWithInstruction(&
I));
5637 if (GreaterThan &&
match(GreaterThan,
m_One()))
5644 if (((Op0HasNSW && Op1HasNSW) || (Op0HasNUW && Op1HasNUW)) &&
5656 if (NonZero && BO0 && BO1 && Op0HasNSW && Op1HasNSW)
5663 if (NonZero && BO0 && BO1 && Op0HasNUW && Op1HasNUW)
5674 else if (BO1 && BO1->
getOpcode() == Instruction::SRem &&
5704 case Instruction::Add:
5705 case Instruction::Sub:
5706 case Instruction::Xor: {
5713 if (
C->isSignMask()) {
5719 if (BO0->
getOpcode() == Instruction::Xor &&
C->isMaxSignedValue()) {
5721 NewPred =
I.getSwappedPredicate(NewPred);
5727 case Instruction::Mul: {
5728 if (!
I.isEquality())
5736 if (
unsigned TZs =
C->countr_zero()) {
5742 return new ICmpInst(Pred, And1, And2);
5747 case Instruction::UDiv:
5748 case Instruction::LShr:
5753 case Instruction::SDiv:
5759 case Instruction::AShr:
5764 case Instruction::Shl: {
5765 bool NUW = Op0HasNUW && Op1HasNUW;
5766 bool NSW = Op0HasNSW && Op1HasNSW;
5769 if (!NSW &&
I.isSigned())
5833 auto IsCondKnownTrue = [](
Value *Val) -> std::optional<bool> {
5835 return std::nullopt;
5840 return std::nullopt;
5846 Pred = Pred.dropSameSign();
5849 if (!CmpXZ.has_value() && !CmpYZ.has_value())
5851 if (!CmpXZ.has_value()) {
5857 if (CmpYZ.has_value())
5881 if (!MinMaxCmpXZ.has_value()) {
5889 if (!MinMaxCmpXZ.has_value())
5905 return FoldIntoCmpYZ();
5932 return FoldIntoCmpYZ();
5941 return FoldIntoCmpYZ();
5973 const APInt *
Lo =
nullptr, *
Hi =
nullptr;
5996 I,
Builder.CreateICmp(Pred,
X, ConstantInt::get(
X->getType(),
C)));
6002 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6006 if (
I.isEquality()) {
6041 Type *Ty =
A->getType();
6042 Value *CtPop = Builder.CreateUnaryIntrinsic(Intrinsic::ctpop,
A);
6044 ConstantInt::get(Ty, 2))
6046 ConstantInt::get(Ty, 1));
6053using OffsetOp = std::pair<Instruction::BinaryOps, Value *>;
6055 bool AllowRecursion) {
6061 case Instruction::Add:
6062 Offsets.emplace_back(Instruction::Sub, Inst->
getOperand(1));
6063 Offsets.emplace_back(Instruction::Sub, Inst->
getOperand(0));
6065 case Instruction::Sub:
6066 Offsets.emplace_back(Instruction::Add, Inst->
getOperand(1));
6068 case Instruction::Xor:
6069 Offsets.emplace_back(Instruction::Xor, Inst->
getOperand(1));
6070 Offsets.emplace_back(Instruction::Xor, Inst->
getOperand(0));
6072 case Instruction::Shl:
6074 Offsets.emplace_back(Instruction::AShr, Inst->
getOperand(1));
6076 Offsets.emplace_back(Instruction::LShr, Inst->
getOperand(1));
6078 case Instruction::Select:
6079 if (AllowRecursion) {
6114 return Builder.CreateSelect(
6127 assert(
I.isEquality() &&
"Expected an equality icmp");
6128 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6139 case Instruction::AShr: {
6140 const APInt *CV, *CRHS;
6142 CV->
ashr(*CRHS).
shl(*CRHS) == *CV) &&
6148 case Instruction::LShr: {
6149 const APInt *CV, *CRHS;
6151 CV->
lshr(*CRHS).
shl(*CRHS) == *CV) &&
6170 auto ApplyOffset = [&](
Value *V,
unsigned BinOpc,
6173 if (!Sel->hasOneUse())
6175 Value *TrueVal = ApplyOffsetImpl(Sel->getTrueValue(), BinOpc,
RHS);
6178 Value *FalseVal = ApplyOffsetImpl(Sel->getFalseValue(), BinOpc,
RHS);
6183 if (
Value *Simplified = ApplyOffsetImpl(V, BinOpc,
RHS))
6188 for (
auto [BinOp,
RHS] : OffsetOps) {
6189 auto BinOpc =
static_cast<unsigned>(BinOp);
6191 auto Op0Result = ApplyOffset(Op0, BinOpc,
RHS);
6192 if (!Op0Result.isValid())
6194 auto Op1Result = ApplyOffset(Op1, BinOpc,
RHS);
6195 if (!Op1Result.isValid())
6198 Value *NewLHS = Op0Result.materialize(Builder);
6199 Value *NewRHS = Op1Result.materialize(Builder);
6200 return new ICmpInst(
I.getPredicate(), NewLHS, NewRHS);
6207 if (!
I.isEquality())
6210 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6214 if (
A == Op1 ||
B == Op1) {
6215 Value *OtherVal =
A == Op1 ?
B :
A;
6243 Value *OtherVal =
A == Op0 ?
B :
A;
6250 Value *
X =
nullptr, *
Y =
nullptr, *Z =
nullptr;
6256 }
else if (
A ==
D) {
6260 }
else if (
B ==
C) {
6264 }
else if (
B ==
D) {
6274 const APInt *C0, *C1;
6276 (*C0 ^ *C1).isNegatedPowerOf2();
6282 int(Op0->
hasOneUse()) + int(Op1->hasOneUse()) +
6284 if (XorIsNegP2 || UseCnt >= 2) {
6287 Op1 =
Builder.CreateAnd(Op1, Z);
6307 (Op0->
hasOneUse() || Op1->hasOneUse())) {
6312 MaskC->
countr_one() ==
A->getType()->getScalarSizeInBits())
6318 const APInt *AP1, *AP2;
6327 if (ShAmt < TypeBits && ShAmt != 0) {
6332 return new ICmpInst(NewPred,
Xor, ConstantInt::get(
A->getType(), CmpVal));
6342 if (ShAmt < TypeBits && ShAmt != 0) {
6362 if (ShAmt < ASize) {
6385 A->getType()->getScalarSizeInBits() ==
BitWidth * 2 &&
6386 (
I.getOperand(0)->hasOneUse() ||
I.getOperand(1)->hasOneUse())) {
6391 Add, ConstantInt::get(
A->getType(),
C.shl(1)));
6418 Builder.CreateIntrinsic(Op0->
getType(), Intrinsic::fshl, {A, A, B}));
6433 std::optional<bool> IsZero = std::nullopt;
6475 Constant *
C = ConstantInt::get(Res->X->getType(), Res->C);
6479 unsigned SrcBits =
X->getType()->getScalarSizeInBits();
6481 if (
II->getIntrinsicID() == Intrinsic::cttz ||
6482 II->getIntrinsicID() == Intrinsic::ctlz) {
6483 unsigned MaxRet = SrcBits;
6509 bool IsSignedExt = CastOp0->getOpcode() == Instruction::SExt;
6510 bool IsSignedCmp = ICmp.
isSigned();
6518 if (IsZext0 != IsZext1) {
6523 if (ICmp.
isEquality() &&
X->getType()->isIntOrIntVectorTy(1) &&
6524 Y->getType()->isIntOrIntVectorTy(1))
6534 bool IsNonNeg0 = NonNegInst0 && NonNegInst0->hasNonNeg();
6535 bool IsNonNeg1 = NonNegInst1 && NonNegInst1->hasNonNeg();
6537 if ((IsZext0 && IsNonNeg0) || (IsZext1 && IsNonNeg1))
6544 Type *XTy =
X->getType(), *YTy =
Y->getType();
6551 IsSignedExt ? Instruction::SExt : Instruction::ZExt;
6553 X =
Builder.CreateCast(CastOpcode,
X, YTy);
6555 Y =
Builder.CreateCast(CastOpcode,
Y, XTy);
6567 if (IsSignedCmp && IsSignedExt)
6580 Type *SrcTy = CastOp0->getSrcTy();
6588 if (IsSignedExt && IsSignedCmp)
6619 Value *SimplifiedOp0 = simplifyIntToPtrRoundTripCast(ICmp.
getOperand(0));
6620 Value *SimplifiedOp1 = simplifyIntToPtrRoundTripCast(ICmp.
getOperand(1));
6621 if (SimplifiedOp0 || SimplifiedOp1)
6623 SimplifiedOp0 ? SimplifiedOp0 : ICmp.
getOperand(0),
6624 SimplifiedOp1 ? SimplifiedOp1 : ICmp.
getOperand(1));
6633 Value *Op0Src = CastOp0->getOperand(0);
6634 Type *SrcTy = CastOp0->getSrcTy();
6635 Type *DestTy = CastOp0->getDestTy();
6639 auto CompatibleSizes = [&](
Type *PtrTy,
Type *IntTy) {
6640 unsigned IntWidth = IntTy->getScalarType()->getIntegerBitWidth();
6641 unsigned IndexWidth =
DL.getAddressSizeInBits(PtrTy);
6642 unsigned PtrWidth =
DL.getPointerTypeSizeInBits(PtrTy);
6645 return IntWidth == IndexWidth && IndexWidth == PtrWidth;
6649 Value *NewOp1 =
nullptr;
6651 NewOp1 = PtrToIntOp1->getOperand(0);
6654 NewOp1 = PtrToAddrOp1->getOperand(0);
6661 if ((!HasPtrToInt || CompatibleSizes(SrcTy, DestTy)) &&
6667 if (CastOp0->getOpcode() == Instruction::IntToPtr &&
6668 CompatibleSizes(DestTy, SrcTy)) {
6669 Value *NewOp1 =
nullptr;
6671 Value *IntSrc = IntToPtrOp1->getOperand(0);
6673 NewOp1 = IntToPtrOp1->getOperand(0);
6693 case Instruction::Add:
6694 case Instruction::Sub:
6696 case Instruction::Mul:
6697 return !(
RHS->getType()->isIntOrIntVectorTy(1) && IsSigned) &&
6709 case Instruction::Add:
6714 case Instruction::Sub:
6719 case Instruction::Mul:
6728 bool IsSigned,
Value *LHS,
6739 Builder.SetInsertPoint(&OrigI);
6756 Result = Builder.CreateBinOp(BinaryOp,
LHS,
RHS);
6757 Result->takeName(&OrigI);
6761 Result = Builder.CreateBinOp(BinaryOp,
LHS,
RHS);
6762 Result->takeName(&OrigI);
6766 Inst->setHasNoSignedWrap();
6768 Inst->setHasNoUnsignedWrap();
6791 const APInt *OtherVal,
6801 assert(MulInstr->getOpcode() == Instruction::Mul);
6805 assert(
LHS->getOpcode() == Instruction::ZExt);
6806 assert(
RHS->getOpcode() == Instruction::ZExt);
6810 Type *TyA =
A->getType(), *TyB =
B->getType();
6812 WidthB = TyB->getPrimitiveSizeInBits();
6815 if (WidthB > WidthA) {
6832 unsigned TruncWidth = TI->getType()->getPrimitiveSizeInBits();
6833 if (TruncWidth > MulWidth)
6837 if (BO->getOpcode() != Instruction::And)
6840 const APInt &CVal = CI->getValue();
6856 switch (
I.getPredicate()) {
6863 if (MaxVal.
eq(*OtherVal))
6873 if (MaxVal.
eq(*OtherVal))
6887 if (WidthA < MulWidth)
6888 MulA = Builder.CreateZExt(
A, MulType);
6889 if (WidthB < MulWidth)
6890 MulB = Builder.CreateZExt(
B, MulType);
6892 Builder.CreateIntrinsic(Intrinsic::umul_with_overflow, MulType,
6893 {MulA, MulB},
nullptr,
"umul");
6900 Value *
Mul = Builder.CreateExtractValue(
Call, 0,
"umul.value");
6905 if (TI->getType()->getPrimitiveSizeInBits() == MulWidth)
6910 assert(BO->getOpcode() == Instruction::And);
6914 Value *ShortAnd = Builder.CreateAnd(
Mul, ShortMask);
6915 Value *Zext = Builder.CreateZExt(ShortAnd, BO->
getType());
6927 Value *Res = Builder.CreateExtractValue(
Call, 1);
6948 switch (
I.getPredicate()) {
6979 assert(DI && UI &&
"Instruction not defined\n");
6991 if (Usr != UI && !
DT.dominates(DB, Usr->getParent()))
7006 if (!IC || (IC->getOperand(0) !=
SI && IC->getOperand(1) !=
SI))
7053 const unsigned SIOpd) {
7054 assert((SIOpd == 1 || SIOpd == 2) &&
"Invalid select operand!");
7056 BasicBlock *Succ =
SI->getParent()->getTerminator()->getSuccessor(1);
7070 SI->replaceUsesOutsideBlock(
SI->getOperand(SIOpd),
SI->getParent());
7080 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7085 unsigned BitWidth = Ty->isIntOrIntVectorTy()
7086 ? Ty->getScalarSizeInBits()
7087 :
DL.getPointerTypeSizeInBits(Ty->getScalarType());
7111 if (
I.hasSameSign() &&
I.isUnsigned()) {
7113 if (To.isNegative() || To.isNonNegative())
7118 To.makeNonNegative();
7120 PropagateSignBit(Op0Known, Op1Known);
7121 PropagateSignBit(Op1Known, Op0Known);
7156 if (!Cmp.hasOneUse())
7165 if (!isMinMaxCmp(
I)) {
7170 if (Op1Min == Op0Max)
7175 if (*CmpC == Op0Min + 1)
7177 ConstantInt::get(Op1->getType(), *CmpC - 1));
7187 if (Op1Max == Op0Min)
7192 if (*CmpC == Op0Max - 1)
7194 ConstantInt::get(Op1->getType(), *CmpC + 1));
7204 if (Op1Min == Op0Max)
7208 if (*CmpC == Op0Min + 1)
7210 ConstantInt::get(Op1->getType(), *CmpC - 1));
7215 if (Op1Max == Op0Min)
7219 if (*CmpC == Op0Max - 1)
7221 ConstantInt::get(Op1->getType(), *CmpC + 1));
7238 APInt Op0KnownZeroInverted = ~Op0Known.Zero;
7241 Value *LHS =
nullptr;
7244 *LHSC != Op0KnownZeroInverted)
7250 Type *XTy =
X->getType();
7252 APInt C2 = Op0KnownZeroInverted;
7253 APInt C2Pow2 = (C2 & ~(*C1 - 1)) + *C1;
7259 auto *CmpC = ConstantInt::get(XTy, Log2C2 - Log2C1);
7269 (Op0Known & Op1Known) == Op0Known)
7275 if (Op1Min == Op0Max)
7279 if (Op1Max == Op0Min)
7283 if (Op1Min == Op0Max)
7287 if (Op1Max == Op0Min)
7295 if ((
I.isSigned() || (
I.isUnsigned() && !
I.hasSameSign())) &&
7298 I.setPredicate(
I.getUnsignedPredicate());
7316 return BinaryOperator::CreateAnd(
Builder.CreateIsNull(
X),
Y);
7322 return BinaryOperator::CreateOr(
Builder.CreateIsNull(
X),
Y);
7333 bool IsSExt = ExtI->
getOpcode() == Instruction::SExt;
7335 auto CreateRangeCheck = [&] {
7350 }
else if (!IsSExt || HasOneUse) {
7355 return CreateRangeCheck();
7357 }
else if (IsSExt ?
C->isAllOnes() :
C->isOne()) {
7365 }
else if (!IsSExt || HasOneUse) {
7370 return CreateRangeCheck();
7384 Instruction::ICmp, Pred1,
X,
7403 Value *Op0 =
I.getOperand(0);
7404 Value *Op1 =
I.getOperand(1);
7410 if (!FlippedStrictness)
7414 new ICmpInst(FlippedStrictness->first, Op0, FlippedStrictness->second);
7415 NewCmp->setSameSign(FlippedStrictness->first.hasSameSign());
7434 I.setName(
I.getName() +
".not");
7445 Value *
A =
I.getOperand(0), *
B =
I.getOperand(1);
7446 assert(
A->getType()->isIntOrIntVectorTy(1) &&
"Bools only");
7452 switch (
I.getPredicate()) {
7461 switch (
I.getPredicate()) {
7471 switch (
I.getPredicate()) {
7480 return BinaryOperator::CreateXor(
A,
B);
7488 return BinaryOperator::CreateAnd(Builder.CreateNot(
A),
B);
7496 return BinaryOperator::CreateAnd(Builder.CreateNot(
B),
A);
7504 return BinaryOperator::CreateOr(Builder.CreateNot(
A),
B);
7512 return BinaryOperator::CreateOr(Builder.CreateNot(
B),
A);
7560 Value *NewX = Builder.CreateLShr(
X,
Y,
X->getName() +
".highbits");
7568 Value *
LHS = Cmp.getOperand(0), *
RHS = Cmp.getOperand(1);
7572 Value *V = Builder.CreateCmp(Pred,
X,
Y, Cmp.getName());
7574 I->copyIRFlags(&Cmp);
7575 Module *M = Cmp.getModule();
7577 M, Intrinsic::vector_reverse, V->getType());
7584 (
LHS->hasOneUse() ||
RHS->hasOneUse()))
7585 return createCmpReverse(Pred,
V1, V2);
7589 return createCmpReverse(Pred,
V1,
RHS);
7593 return createCmpReverse(Pred,
LHS, V2);
7602 Type *V1Ty =
V1->getType();
7604 V1Ty == V2->
getType() && (
LHS->hasOneUse() ||
RHS->hasOneUse())) {
7605 Value *NewCmp = Builder.CreateCmp(Pred,
V1, V2);
7618 Constant *ScalarC =
C->getSplatValue(
true);
7626 Value *NewCmp = Builder.CreateCmp(Pred,
V1,
C);
7637 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7643 if (
match(Op0, UAddOvResultPat) &&
7654 (Op0 ==
A || Op0 ==
B))
7664 if (!
I.getOperand(0)->getType()->isPointerTy() ||
7666 I.getParent()->getParent(),
7667 I.getOperand(0)->getType()->getPointerAddressSpace())) {
7673 Op->isLaunderOrStripInvariantGroup()) {
7675 Op->getOperand(0),
I.getOperand(1));
7687 Value *Const =
I.getOperand(1);
7705 Type *VecEltTy = VecTy->getElementType();
7707 DL.getTypeSizeInBits(VecEltTy) * VecTy->getNumElements();
7708 if (!
DL.fitsInLegalInteger(ScalarBW))
7712 ? ConstantInt::get(ScalarTy, 0)
7715 Builder.CreateBitCast(Vec, ScalarTy), NewConst);
7727 if (
I.getType()->isVectorTy())
7750 if (!LHSTy || !LHSTy->getElementType()->isIntegerTy())
7753 LHSTy->getNumElements() * LHSTy->getElementType()->getIntegerBitWidth();
7755 if (!
DL.isLegalInteger(NumBits))
7759 auto *ScalarTy = Builder.getIntNTy(NumBits);
7760 LHS = Builder.CreateBitCast(
LHS, ScalarTy,
LHS->getName() +
".scalar");
7761 RHS = Builder.CreateBitCast(
RHS, ScalarTy,
RHS->getName() +
".scalar");
7817 bool IsIntMinPosion =
C->isAllOnesValue();
7829 CxtI, IsIntMinPosion
7830 ?
Builder.CreateICmpSGT(
X, AllOnesValue)
7832 X, ConstantInt::get(
X->getType(),
SMin + 1)));
7838 CxtI, IsIntMinPosion
7839 ?
Builder.CreateICmpSLT(
X, NullValue)
7841 X, ConstantInt::get(
X->getType(),
SMin)));
7854 auto CheckUGT1 = [](
const APInt &Divisor) {
return Divisor.ugt(1); };
7869 auto CheckNE0 = [](
const APInt &Shift) {
return !Shift.isZero(); };
7890 if (ShAmt >=
X->getType()->getScalarSizeInBits())
7892 if (canEvaluateShifted(Op1, ShAmt,
false,
7894 Value *NewOp1 = getShiftedValue(Op1, ShAmt,
false,
7902 if (ShAmt >=
X->getType()->getScalarSizeInBits())
7904 if (canEvaluateShifted(Op1, ShAmt,
false,
7906 Value *NewOp1 = getShiftedValue(Op1, ShAmt,
false,
7917 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7924 if (Op0Cplxity < Op1Cplxity) {
7939 if (
Value *V = dyn_castNegVal(SelectTrue)) {
7940 if (V == SelectFalse)
7942 }
else if (
Value *V = dyn_castNegVal(SelectFalse)) {
7943 if (V == SelectTrue)
8003 if (
C->isNonNegative())
8007 ConstantInt::get(
X->getType(), ~*
C));
8013 if (
C->isNonNegative())
8017 ConstantInt::get(
X->getType(), ~*
C));
8073 if (
I.isCommutative()) {
8074 if (
auto Pair = matchSymmetricPair(
I.getOperand(0),
I.getOperand(1))) {
8103 (Op0->
hasOneUse() || Op1->hasOneUse())) {
8108 Cond, Res, NewICMP,
"",
nullptr,
8115 Cond, NewICMP, Res,
"",
nullptr,
8131 bool I0NUW = I0->hasNoUnsignedWrap();
8132 bool I1NUW = I1->hasNoUnsignedWrap();
8133 bool I0NSW = I0->hasNoSignedWrap();
8134 bool I1NSW = I1->hasNoSignedWrap();
8138 ((I0NUW || I0NSW) && (I1NUW || I1NSW)))) {
8140 ConstantInt::get(Op0->
getType(), 0));
8147 assert(Op1->getType()->isPointerTy() &&
8148 "Comparing pointer with non-pointer?");
8177 bool ConsumesOp0, ConsumesOp1;
8180 (ConsumesOp0 || ConsumesOp1)) {
8183 assert(InvOp0 && InvOp1 &&
8184 "Mismatch between isFreeToInvert and getFreelyInverted");
8185 return new ICmpInst(
I.getSwappedPredicate(), InvOp0, InvOp1);
8197 if (AddI->
getOpcode() == Instruction::Add &&
8198 OptimizeOverflowCheck(Instruction::Add,
false,
X,
Y, *AddI,
8199 Result, Overflow)) {
8217 if ((
I.isUnsigned() ||
I.isEquality()) &&
8220 Y->getType()->getScalarSizeInBits() == 1 &&
8221 (Op0->
hasOneUse() || Op1->hasOneUse())) {
8228 unsigned ShiftOpc = ShiftI->
getOpcode();
8229 if ((ExtOpc == Instruction::ZExt && ShiftOpc == Instruction::LShr) ||
8230 (ExtOpc == Instruction::SExt && ShiftOpc == Instruction::AShr)) {
8264 if (EVI->getIndices()[0] == 0 && ACXI->getCompareOperand() == Op1 &&
8271 if (
I.getType()->isVectorTy())
8283 const APInt *C1, *C2;
8290 Type *InputTy =
A->getType();
8297 TruncC1.
setBit(InputBitWidth - 1);
8301 ConstantInt::get(InputTy, C2->
trunc(InputBitWidth)));
8321 if (MantissaWidth == -1)
8328 if (
I.isEquality()) {
8330 bool IsExact =
false;
8331 APSInt RHSCvt(IntWidth, LHSUnsigned);
8340 if (*RHS != RHSRoundInt) {
8360 if ((
int)IntWidth > MantissaWidth) {
8362 int Exp =
ilogb(*RHS);
8365 if (MaxExponent < (
int)IntWidth - !LHSUnsigned)
8371 if (MantissaWidth <= Exp && Exp <= (
int)IntWidth - !LHSUnsigned)
8380 assert(!RHS->isNaN() &&
"NaN comparison not already folded!");
8383 switch (
I.getPredicate()) {
8474 APSInt RHSInt(IntWidth, LHSUnsigned);
8477 if (!RHS->isZero()) {
8492 if (RHS->isNegative())
8498 if (RHS->isNegative())
8504 if (RHS->isNegative())
8511 if (!RHS->isNegative())
8517 if (RHS->isNegative())
8523 if (RHS->isNegative())
8529 if (RHS->isNegative())
8536 if (!RHS->isNegative())
8555 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
8566 unsigned Pred =
I.getPredicate();
8574 if (!Res00 || !Res01 || !Res10 || !Res11)
8583 std::bitset<4>
Table;
8641 if (
C->isNegative())
8642 Pred =
I.getSwappedPredicate();
8669 "X ord/uno NaN should be folded away by simplifyFCmpInst()");
8675 bool RoundDown =
false;
8696 auto NextValue = [](
const APFloat &
Value,
bool RoundDown) {
8698 NextValue.
next(RoundDown);
8702 APFloat NextCValue = NextValue(*CValue, RoundDown);
8707 APFloat ExtCValue = ConvertFltSema(*CValue, DestFltSema);
8708 APFloat ExtNextCValue = ConvertFltSema(NextCValue, DestFltSema);
8715 APFloat PrevCValue = NextValue(*CValue, !RoundDown);
8716 APFloat Bias = ConvertFltSema(*CValue - PrevCValue, DestFltSema);
8718 ExtNextCValue = ExtCValue + Bias;
8725 C.getType()->getScalarType()->getFltSemantics();
8728 APFloat MidValue = ConvertFltSema(ExtMidValue, SrcFltSema);
8729 if (MidValue != *CValue)
8730 ExtMidValue.
next(!RoundDown);
8738 if (ConvertFltSema(ExtMidValue, SrcFltSema).isInfinity())
8742 APFloat NextExtMidValue = NextValue(ExtMidValue, RoundDown);
8743 if (ConvertFltSema(NextExtMidValue, SrcFltSema).
isFinite())
8748 ConstantFP::get(DestType, ExtMidValue),
"", &
I);
8761 if (!
C->isPosZero()) {
8762 if (!
C->isSmallestNormalized())
8775 switch (
I.getPredicate()) {
8801 switch (
I.getPredicate()) {
8826 assert(!
I.hasNoNaNs() &&
"fcmp should have simplified");
8831 assert(!
I.hasNoNaNs() &&
"fcmp should have simplified");
8845 return replacePredAndOp0(&
I,
I.getPredicate(),
X);
8868 I.setHasNoInfs(
false);
8870 switch (
I.getPredicate()) {
8915 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
8920 Pred =
I.getSwappedPredicate();
8929 return new FCmpInst(Pred, Op0, Zero,
"", &
I);
8965 I.getFunction()->getDenormalMode(
8972 I.setHasNoNaNs(
true);
8997 if (MantissaWidth != -1 &&
ilogb(*
C) < MantissaWidth) {
8999 I.setPredicate(
I.getSwappedPredicate());
9036 if (!IsStrictLt && !IsStrictGt && !IsGe)
9058 }
else if (
match(FAbsArg,
9066 if (
A->getType() !=
B->getType())
9081 Type *OpType =
LHS->getType();
9087 if (!FloorX && !CeilX) {
9091 Pred =
I.getSwappedPredicate();
9167 if (!
I || !(
I->getOpcode() == Instruction::SIToFP ||
9168 I->getOpcode() == Instruction::UIToFP))
9171 bool IsUnsigned =
I->getOpcode() == Instruction::UIToFP;
9172 unsigned BitWidth =
I->getOperand(0)->getType()->getScalarSizeInBits();
9195 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
9197 SQ.getWithInstruction(&
I)))
9202 assert(OpType == Op1->getType() &&
"fcmp with different-typed operands?");
9227 if (
I.isCommutative()) {
9228 if (
auto Pair = matchSymmetricPair(
I.getOperand(0),
I.getOperand(1))) {
9250 return new FCmpInst(
I.getSwappedPredicate(),
X,
Y,
"", &
I);
9266 bool IsRedundantMinMaxClamp =
9328 X->getType()->isIntOrIntVectorTy() &&
9329 !
F.getDenormalMode(Op1->getType()->getScalarType()->getFltSemantics())
9330 .inputsMayBeZero()) {
9338 Type *IntTy =
X->getType();
9339 const APInt &SignMask =
~APInt::getSignMask(IntTy->getScalarSizeInBits());
9340 Value *MaskX =
Builder.CreateAnd(
X, ConstantInt::get(IntTy, SignMask));
9350 case Instruction::Select:
9358 case Instruction::FSub:
9363 case Instruction::PHI:
9367 case Instruction::SIToFP:
9368 case Instruction::UIToFP:
9372 case Instruction::FDiv:
9376 case Instruction::Load:
9382 case Instruction::FPTrunc:
9409 return new FCmpInst(
I.getSwappedPredicate(),
X, NegC,
"", &
I);
9423 X->getType() ==
Y->getType())
9434 X->getType()->getScalarType()->getFltSemantics();
9470 Constant *NewC = ConstantFP::get(
X->getType(), TruncC);
9483 Type *IntType =
Builder.getIntNTy(
X->getType()->getScalarSizeInBits());
9496 Value *CanonLHS =
nullptr;
9499 if (CanonLHS == Op1)
9500 return new FCmpInst(Pred, Op1, Op1,
"", &
I);
9502 Value *CanonRHS =
nullptr;
9505 if (CanonRHS == Op0)
9506 return new FCmpInst(Pred, Op0, Op0,
"", &
I);
9509 if (CanonLHS && CanonRHS)
9510 return new FCmpInst(Pred, CanonLHS, CanonRHS,
"", &
I);
9513 if (
I.getType()->isVectorTy())
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static Instruction * foldFCmpReciprocalAndZero(FCmpInst &I, Instruction *LHSI, Constant *RHSC)
Fold (C / X) < 0.0 --> X < 0.0 if possible. Swap predicate if necessary.
static Instruction * foldFabsWithFcmpZero(FCmpInst &I, InstCombinerImpl &IC)
Optimize fabs(X) compared with zero.
static void collectOffsetOp(Value *V, SmallVectorImpl< OffsetOp > &Offsets, bool AllowRecursion)
static Value * rewriteGEPAsOffset(Value *Start, Value *Base, GEPNoWrapFlags NW, const DataLayout &DL, SetVector< Value * > &Explored, InstCombiner &IC)
Returns a re-written value of Start as an indexed GEP using Base as a pointer.
static bool isMinMaxCmpSelectEliminable(SelectPatternFlavor Flavor, Value *A, Value *B)
Returns true if a select that implements a min/max is redundant and select result can be replaced wit...
static Instruction * foldICmpEqualityWithOffset(ICmpInst &I, InstCombiner::BuilderTy &Builder, const SimplifyQuery &SQ)
Offset both sides of an equality icmp to see if we can save some instructions: icmp eq/ne X,...
static bool addWithOverflow(APInt &Result, const APInt &In1, const APInt &In2, bool IsSigned=false)
Compute Result = In1+In2, returning true if the result overflowed for this type.
static Instruction * foldICmpOfVectorReduce(ICmpInst &I, const DataLayout &DL, IRBuilderBase &Builder)
static Instruction * foldICmpAndXX(ICmpInst &I, const SimplifyQuery &Q, InstCombinerImpl &IC)
static Instruction * foldVectorCmp(CmpInst &Cmp, InstCombiner::BuilderTy &Builder)
static bool isMaskOrZero(const Value *V, bool Not, const SimplifyQuery &Q, unsigned Depth=0)
static Value * createLogicFromTable(const std::bitset< 4 > &Table, Value *Op0, Value *Op1, IRBuilderBase &Builder, bool HasOneUse)
static Instruction * foldICmpOfUAddOv(ICmpInst &I)
static bool isChainSelectCmpBranch(const SelectInst *SI)
Return true when the instruction sequence within a block is select-cmp-br.
static Instruction * foldICmpInvariantGroup(ICmpInst &I)
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
static Instruction * foldReductionIdiom(ICmpInst &I, InstCombiner::BuilderTy &Builder, const DataLayout &DL)
This function folds patterns produced by lowering of reduce idioms, such as llvm.vector....
static Instruction * canonicalizeICmpBool(ICmpInst &I, InstCombiner::BuilderTy &Builder)
Integer compare with boolean values can always be turned into bitwise ops.
static Instruction * foldFCmpFSubIntoFCmp(FCmpInst &I, Instruction *LHSI, Constant *RHSC, InstCombinerImpl &CI)
static Value * foldICmpOrXorSubChain(ICmpInst &Cmp, BinaryOperator *Or, InstCombiner::BuilderTy &Builder)
Fold icmp eq/ne (or (xor/sub (X1, X2), xor/sub (X3, X4))), 0.
static bool hasBranchUse(ICmpInst &I)
Given an icmp instruction, return true if any use of this comparison is a branch on sign bit comparis...
static Value * foldICmpWithLowBitMaskedVal(CmpPredicate Pred, Value *Op0, Value *Op1, const SimplifyQuery &Q, InstCombiner &IC)
Some comparisons can be simplified.
static APInt getDemandedBitsLHSMask(ICmpInst &I, unsigned BitWidth)
When performing a comparison against a constant, it is possible that not all the bits in the LHS are ...
static Instruction * foldICmpShlLHSC(ICmpInst &Cmp, Instruction *Shl, const APInt &C)
Fold icmp (shl nuw C2, Y), C.
static Instruction * foldFCmpWithFloorAndCeil(FCmpInst &I, InstCombinerImpl &IC)
static Instruction * foldICmpXorXX(ICmpInst &I, const SimplifyQuery &Q, InstCombinerImpl &IC)
static Instruction * foldICmpOfCmpIntrinsicWithConstant(CmpPredicate Pred, IntrinsicInst *I, const APInt &C, InstCombiner::BuilderTy &Builder)
static Instruction * processUMulZExtIdiom(ICmpInst &I, Value *MulVal, const APInt *OtherVal, InstCombinerImpl &IC)
Recognize and process idiom involving test for multiplication overflow.
static Instruction * foldSqrtWithFcmpZero(FCmpInst &I, InstCombinerImpl &IC)
Optimize sqrt(X) compared with zero.
static Instruction * foldFCmpFNegCommonOp(FCmpInst &I)
static Instruction * foldICmpWithHighBitMask(ICmpInst &Cmp, InstCombiner::BuilderTy &Builder)
static ICmpInst * canonicalizeCmpWithConstant(ICmpInst &I)
If we have an icmp le or icmp ge instruction with a constant operand, turn it into the appropriate ic...
static Instruction * foldICmpIntrinsicWithIntrinsic(ICmpInst &Cmp, InstCombiner::BuilderTy &Builder)
Fold an icmp with LLVM intrinsics.
static Instruction * foldICmpUSubSatOrUAddSatWithConstant(CmpPredicate Pred, SaturatingInst *II, const APInt &C, InstCombiner::BuilderTy &Builder)
static Instruction * foldICmpPow2Test(ICmpInst &I, InstCombiner::BuilderTy &Builder)
static bool subWithOverflow(APInt &Result, const APInt &In1, const APInt &In2, bool IsSigned=false)
Compute Result = In1-In2, returning true if the result overflowed for this type.
static bool canRewriteGEPAsOffset(Value *Start, Value *Base, GEPNoWrapFlags &NW, const DataLayout &DL, SetVector< Value * > &Explored)
Returns true if we can rewrite Start as a GEP with pointer Base and some integer offset.
static Instruction * 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.
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)
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.
iterator find(const_arg_type_t< KeyT > Val)
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
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.
CmpInst * canonicalizeICmpPredicate(CmpInst &I)
If we have a comparison with a non-canonical predicate, if we can update all the users,...
Instruction * eraseInstFromFunction(Instruction &I) override
Combiner aware instruction erasure.
Instruction * foldICmpWithZero(ICmpInst &Cmp)
Instruction * foldICmpCommutative(CmpPredicate Pred, Value *Op0, Value *Op1, ICmpInst &CxtI)
Instruction * foldICmpBinOpEqualityWithConstant(ICmpInst &Cmp, BinaryOperator *BO, const APInt &C)
Fold an icmp equality instruction with binary operator LHS and constant RHS: icmp eq/ne BO,...
Instruction * foldICmpUsingBoolRange(ICmpInst &I)
If one operand of an icmp is effectively a bool (value range of {0,1}), then try to reduce patterns b...
Instruction * foldICmpWithTrunc(ICmpInst &Cmp)
Instruction * 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,...
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 * 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)
OverflowResult computeOverflow(Instruction::BinaryOps BinaryOp, bool IsSigned, Value *LHS, Value *RHS, Instruction *CxtI) const
Instruction * foldICmpWithDominatingICmp(ICmpInst &Cmp)
Canonicalize icmp instructions based on dominating conditions.
bool replacedSelectWithOperand(SelectInst *SI, const ICmpInst *Icmp, const unsigned SIOpd)
Try to replace select with select operand SIOpd in SI-ICmp sequence.
Instruction * foldICmpShrConstConst(ICmpInst &I, Value *ShAmt, const APInt &C1, const APInt &C2)
Handle "(icmp eq/ne (ashr/lshr AP2, A), AP1)" -> (icmp eq/ne A, Log2(AP2/AP1)) -> (icmp eq/ne A,...
void freelyInvertAllUsersOf(Value *V, Value *IgnoredUser=nullptr)
Freely adapt every user of V as-if V was changed to !V.
Instruction * foldICmpAndConstConst(ICmpInst &Cmp, BinaryOperator *And, const APInt &C1)
Fold icmp (and X, C2), C1.
Instruction * foldICmpBitCast(ICmpInst &Cmp)
Instruction * foldGEPICmp(GEPOperator *GEPLHS, Value *RHS, CmpPredicate Cond, Instruction &I)
Fold comparisons between a GEP instruction and something else.
The core instruction combiner logic.
OverflowResult computeOverflowForSignedSub(const Value *LHS, const Value *RHS, const Instruction *CxtI) const
unsigned ComputeMaxSignificantBits(const Value *Op, const Instruction *CxtI=nullptr, unsigned Depth=0) const
bool isFreeToInvert(Value *V, bool WillInvertAllUses, bool &DoesConsume)
Return true if the specified value is free to invert (apply ~ to).
OverflowResult computeOverflowForUnsignedMul(const Value *LHS, const Value *RHS, const Instruction *CxtI, bool IsNSW=false) const
static unsigned getComplexity(Value *V)
Assign a complexity or rank value to LLVM Values.
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
uint64_t MaxArraySizeForCombine
Maximum size of array considered when transforming.
LLVM_ABI bool canBeCastedExactlyIntToFP(Value *V, Type *FPTy, bool IsSigned, const Instruction *CxtI=nullptr) const
OverflowResult computeOverflowForSignedAdd(const WithCache< const Value * > &LHS, const WithCache< const Value * > &RHS, const Instruction *CxtI) const
static Constant * SubOne(Constant *C)
Subtract one from a Constant.
OverflowResult computeOverflowForUnsignedSub(const Value *LHS, const Value *RHS, const Instruction *CxtI) const
static bool isCanonicalPredicate(CmpPredicate Pred)
Predicate canonicalization reduces the number of patterns that need to be matched by other transforms...
void computeKnownBits(const Value *V, KnownBits &Known, const Instruction *CxtI, unsigned Depth=0) const
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 ?
void addToWorklist(Instruction *I)
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
OverflowResult computeOverflowForSignedMul(const Value *LHS, const Value *RHS, const Instruction *CxtI) const
OverflowResult computeOverflowForUnsignedAdd(const WithCache< const Value * > &LHS, const WithCache< const Value * > &RHS, const Instruction *CxtI) const
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
const SimplifyQuery & getSimplifyQuery() const
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, const Instruction *CxtI=nullptr, unsigned Depth=0)
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.
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.
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.
LLVM_ABI cl::opt< bool > ProfcheckDisableMetadataFixes
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,...
LLVM_ABI Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Instruction *I=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
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 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 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.
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 void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=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 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.
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 isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, AssumptionCache *AC=nullptr, const Instruction *CxtI=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 const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
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.