39#define DEBUG_TYPE "instcombine"
51 bool IsSigned =
false) {
54 Result = In1.
sadd_ov(In2, Overflow);
56 Result = In1.
uadd_ov(In2, Overflow);
64 bool IsSigned =
false) {
67 Result = In1.
ssub_ov(In2, Overflow);
69 Result = In1.
usub_ov(In2, Overflow);
77 for (
auto *U :
I.users())
99 }
else if (
C.isAllOnes()) {
120 if (LI->
isVolatile() || !GV || !GV->isConstant() ||
121 !GV->hasDefinitiveInitializer())
125 TypeSize EltSize =
DL.getTypeStoreSize(EltTy);
141 if (!ConstOffset.
ult(Stride))
155 enum { Overdefined = -3, Undefined = -2 };
164 int FirstTrueElement = Undefined, SecondTrueElement = Undefined;
168 int FirstFalseElement = Undefined, SecondFalseElement = Undefined;
176 int TrueRangeEnd = Undefined, FalseRangeEnd = Undefined;
186 for (
unsigned i = 0, e = ArrayElementCount; i != e; ++i,
Offset += Stride) {
200 CompareRHS,
DL, &
TLI);
208 if (TrueRangeEnd == (
int)i - 1)
210 if (FalseRangeEnd == (
int)i - 1)
227 if (FirstTrueElement == Undefined)
228 FirstTrueElement = TrueRangeEnd = i;
231 if (SecondTrueElement == Undefined)
232 SecondTrueElement = i;
234 SecondTrueElement = Overdefined;
237 if (TrueRangeEnd == (
int)i - 1)
240 TrueRangeEnd = Overdefined;
244 if (FirstFalseElement == Undefined)
245 FirstFalseElement = FalseRangeEnd = i;
248 if (SecondFalseElement == Undefined)
249 SecondFalseElement = i;
251 SecondFalseElement = Overdefined;
254 if (FalseRangeEnd == (
int)i - 1)
257 FalseRangeEnd = Overdefined;
262 if (i < 64 && IsTrueForElt)
263 MagicBitvector |= 1ULL << i;
268 if ((i & 8) == 0 && i >= 64 && SecondTrueElement == Overdefined &&
269 SecondFalseElement == Overdefined && TrueRangeEnd == Overdefined &&
270 FalseRangeEnd == Overdefined)
284 auto MaskIdx = [&](
Value *Idx) {
288 Idx =
Builder.CreateAnd(Idx, Mask);
295 if (SecondTrueElement != Overdefined) {
298 if (FirstTrueElement == Undefined)
301 Value *FirstTrueIdx = ConstantInt::get(Idx->
getType(), FirstTrueElement);
304 if (SecondTrueElement == Undefined)
309 Value *SecondTrueIdx = ConstantInt::get(Idx->
getType(), SecondTrueElement);
311 return BinaryOperator::CreateOr(C1, C2);
316 if (SecondFalseElement != Overdefined) {
319 if (FirstFalseElement == Undefined)
322 Value *FirstFalseIdx = ConstantInt::get(Idx->
getType(), FirstFalseElement);
325 if (SecondFalseElement == Undefined)
330 Value *SecondFalseIdx =
331 ConstantInt::get(Idx->
getType(), SecondFalseElement);
333 return BinaryOperator::CreateAnd(C1, C2);
338 if (TrueRangeEnd != Overdefined) {
339 assert(TrueRangeEnd != FirstTrueElement &&
"Should emit single compare");
343 if (FirstTrueElement) {
345 Idx =
Builder.CreateAdd(Idx, Offs);
349 ConstantInt::get(Idx->
getType(), TrueRangeEnd - FirstTrueElement + 1);
354 if (FalseRangeEnd != Overdefined) {
355 assert(FalseRangeEnd != FirstFalseElement &&
"Should emit single compare");
358 if (FirstFalseElement) {
360 Idx =
Builder.CreateAdd(Idx, Offs);
364 ConstantInt::get(Idx->
getType(), FalseRangeEnd - FirstFalseElement);
377 if (ArrayElementCount <= Idx->
getType()->getIntegerBitWidth())
380 Ty =
DL.getSmallestLegalIntType(
Init->getContext(), ArrayElementCount);
385 V =
Builder.CreateLShr(ConstantInt::get(Ty, MagicBitvector), V);
386 V =
Builder.CreateAnd(ConstantInt::get(Ty, 1), V);
411 while (!WorkList.
empty()) {
414 while (!WorkList.
empty()) {
415 if (Explored.
size() >= 100)
433 if (!
GEP->isInBounds() ||
count_if(
GEP->indices(), IsNonConst) > 1)
441 if (WorkList.
back() == V) {
457 for (
auto *PN : PHIs)
458 for (
Value *
Op : PN->incoming_values())
466 for (
Value *Val : Explored) {
472 if (Inst ==
Base || Inst ==
PHI || !Inst || !
PHI ||
476 if (
PHI->getParent() == Inst->getParent())
486 bool Before =
true) {
494 I = &*std::next(
I->getIterator());
495 Builder.SetInsertPoint(
I);
500 BasicBlock &Entry =
A->getParent()->getEntryBlock();
501 Builder.SetInsertPoint(&Entry, Entry.getFirstInsertionPt());
523 Base->getContext(),
DL.getIndexTypeSizeInBits(Start->getType()));
529 for (
Value *Val : Explored) {
537 PHI->getName() +
".idx",
PHI->getIterator());
542 for (
Value *Val : Explored) {
551 NewInsts[
GEP] = OffsetV;
553 NewInsts[
GEP] = Builder.CreateAdd(
554 Op, OffsetV,
GEP->getOperand(0)->getName() +
".add",
566 for (
Value *Val : Explored) {
573 for (
unsigned I = 0,
E =
PHI->getNumIncomingValues();
I <
E; ++
I) {
574 Value *NewIncoming =
PHI->getIncomingValue(
I);
576 auto It = NewInsts.
find(NewIncoming);
577 if (It != NewInsts.
end())
578 NewIncoming = It->second;
585 for (
Value *Val : Explored) {
591 Value *NewVal = Builder.CreateGEP(Builder.getInt8Ty(),
Base, NewInsts[Val],
592 Val->getName() +
".ptr", NW);
599 return NewInsts[Start];
685 if (
Base.Ptr == RHS && CanFold(
Base.LHSNW) && !
Base.isExpensive()) {
689 EmitGEPOffsets(
Base.LHSGEPs,
Base.LHSNW, IdxTy,
true);
697 RHS->getType()->getPointerAddressSpace())) {
728 if (GEPLHS->
getOperand(0) != GEPRHS->getOperand(0)) {
729 bool IndicesTheSame =
732 GEPRHS->getPointerOperand()->getType() &&
736 if (GEPLHS->
getOperand(i) != GEPRHS->getOperand(i)) {
737 IndicesTheSame =
false;
743 if (IndicesTheSame &&
751 if (GEPLHS->
isInBounds() && GEPRHS->isInBounds() &&
753 (GEPRHS->hasAllConstantIndices() || GEPRHS->hasOneUse()) &&
757 Value *LOffset = EmitGEPOffset(GEPLHS);
758 Value *ROffset = EmitGEPOffset(GEPRHS);
765 if (LHSIndexTy != RHSIndexTy) {
768 ROffset =
Builder.CreateTrunc(ROffset, LHSIndexTy);
770 LOffset =
Builder.CreateTrunc(LOffset, RHSIndexTy);
779 if (GEPLHS->
getOperand(0) == GEPRHS->getOperand(0) &&
783 unsigned NumDifferences = 0;
784 unsigned DiffOperand = 0;
785 for (
unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i)
786 if (GEPLHS->
getOperand(i) != GEPRHS->getOperand(i)) {
788 Type *RHSType = GEPRHS->getOperand(i)->getType();
799 if (NumDifferences++)
804 if (NumDifferences == 0)
812 Value *RHSV = GEPRHS->getOperand(DiffOperand);
813 return NewICmp(NW, LHSV, RHSV);
821 EmitGEPOffsets(
Base.LHSGEPs,
Base.LHSNW, IdxTy,
true);
823 EmitGEPOffsets(
Base.RHSGEPs,
Base.RHSNW, IdxTy,
true);
824 return NewICmp(
Base.LHSNW &
Base.RHSNW, L, R);
850 bool Captured =
false;
855 CmpCaptureTracker(
AllocaInst *Alloca) : Alloca(Alloca) {}
857 void tooManyUses()
override { Captured =
true; }
869 ICmps[ICmp] |= 1u << U->getOperandNo();
878 CmpCaptureTracker Tracker(Alloca);
880 if (Tracker.Captured)
884 for (
auto [ICmp, Operands] : Tracker.ICmps) {
890 auto *Res = ConstantInt::get(ICmp->getType(),
916 assert(!!
C &&
"C should not be zero!");
932 ConstantInt::get(
X->getType(), -
C));
944 ConstantInt::get(
X->getType(),
SMax -
C));
955 ConstantInt::get(
X->getType(),
SMax - (
C - 1)));
964 assert(
I.isEquality() &&
"Cannot fold icmp gt/lt");
967 if (
I.getPredicate() ==
I.ICMP_NE)
969 return new ICmpInst(Pred, LHS, RHS);
988 return getICmp(
I.ICMP_UGT,
A,
989 ConstantInt::get(
A->getType(), AP2.
logBase2()));
1001 if (IsAShr && AP1 == AP2.
ashr(Shift)) {
1005 return getICmp(
I.ICMP_UGE,
A, ConstantInt::get(
A->getType(), Shift));
1006 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1007 }
else if (AP1 == AP2.
lshr(Shift)) {
1008 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1014 auto *TorF = ConstantInt::get(
I.getType(),
I.getPredicate() ==
I.ICMP_NE);
1023 assert(
I.isEquality() &&
"Cannot fold icmp gt/lt");
1026 if (
I.getPredicate() ==
I.ICMP_NE)
1028 return new ICmpInst(Pred, LHS, RHS);
1037 if (!AP1 && AP2TrailingZeros != 0)
1040 ConstantInt::get(
A->getType(), AP2.
getBitWidth() - AP2TrailingZeros));
1048 if (Shift > 0 && AP2.
shl(Shift) == AP1)
1049 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1053 auto *TorF = ConstantInt::get(
I.getType(),
I.getPredicate() ==
I.ICMP_NE);
1082 if (NewWidth != 7 && NewWidth != 15 && NewWidth != 31)
1106 if (U == AddWithCst)
1124 I.getModule(), Intrinsic::sadd_with_overflow, NewType);
1132 Value *TruncA = Builder.CreateTrunc(
A, NewType,
A->getName() +
".trunc");
1133 Value *TruncB = Builder.CreateTrunc(
B, NewType,
B->getName() +
".trunc");
1134 CallInst *
Call = Builder.CreateCall(
F, {TruncA, TruncB},
"sadd");
1135 Value *
Add = Builder.CreateExtractValue(
Call, 0,
"sadd.result");
1153 if (!
I.isEquality())
1184 APInt(XBitWidth, XBitWidth - 1))))
1211 return new ICmpInst(Pred,
B, Cmp.getOperand(1));
1213 return new ICmpInst(Pred,
A, Cmp.getOperand(1));
1230 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1242 return new ICmpInst(Pred,
Y, Cmp.getOperand(1));
1248 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1251 if (BO0->hasNoUnsignedWrap() || BO0->hasNoSignedWrap()) {
1259 return new ICmpInst(Pred,
Y, Cmp.getOperand(1));
1264 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1280 return new ICmpInst(Pred, Stripped,
1293 const APInt *Mask, *Neg;
1309 auto *NewAnd =
Builder.CreateAnd(Num, *Mask);
1312 return new ICmpInst(Pred, NewAnd, Zero);
1333 Value *Op0 = Cmp.getOperand(0), *Op1 = Cmp.getOperand(1);
1349 for (
Value *V : Phi->incoming_values()) {
1357 PHINode *NewPhi =
Builder.CreatePHI(Cmp.getType(), Phi->getNumOperands());
1358 for (
auto [V, Pred] :
zip(
Ops, Phi->blocks()))
1373 Value *
X = Cmp.getOperand(0), *
Y = Cmp.getOperand(1);
1406 if (Cmp.isEquality() || (IsSignBit &&
hasBranchUse(Cmp)))
1411 if (Cmp.hasOneUse() &&
1425 if (!
match(BI->getCondition(),
1430 if (
DT.dominates(Edge0, Cmp.getParent())) {
1431 if (
auto *V = handleDomCond(DomPred, DomC))
1435 if (
DT.dominates(Edge1, Cmp.getParent()))
1451 Type *SrcTy =
X->getType();
1453 SrcBits = SrcTy->getScalarSizeInBits();
1457 if (shouldChangeType(Trunc->
getType(), SrcTy)) {
1459 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy,
C.sext(SrcBits)));
1461 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy,
C.zext(SrcBits)));
1464 if (
C.isOne() &&
C.getBitWidth() > 1) {
1469 ConstantInt::get(V->getType(), 1));
1481 auto NewPred = (Pred == Cmp.ICMP_EQ) ? Cmp.ICMP_UGE : Cmp.ICMP_ULT;
1483 ConstantInt::get(SrcTy, DstBits - Pow2->
logBase2()));
1489 Pred,
Y, ConstantInt::get(SrcTy,
C.logBase2() - Pow2->
logBase2()));
1495 if (!SrcTy->isVectorTy() && shouldChangeType(DstBits, SrcBits)) {
1499 Constant *WideC = ConstantInt::get(SrcTy,
C.zext(SrcBits));
1508 if ((Known.
Zero | Known.
One).countl_one() >= SrcBits - DstBits) {
1510 APInt NewRHS =
C.zext(SrcBits);
1512 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy, NewRHS));
1524 DstBits == SrcBits - ShAmt) {
1541 bool YIsSExt =
false;
1544 unsigned NoWrapFlags =
cast<TruncInst>(Cmp.getOperand(0))->getNoWrapKind() &
1546 if (Cmp.isSigned()) {
1557 if (
X->getType() !=
Y->getType() &&
1558 (!Cmp.getOperand(0)->hasOneUse() || !Cmp.getOperand(1)->hasOneUse()))
1560 if (!isDesirableIntType(
X->getType()->getScalarSizeInBits()) &&
1561 isDesirableIntType(
Y->getType()->getScalarSizeInBits())) {
1563 Pred = Cmp.getSwappedPredicate(Pred);
1568 else if (!Cmp.isSigned() &&
1582 Type *TruncTy = Cmp.getOperand(0)->getType();
1587 if (isDesirableIntType(TruncBits) &&
1588 !isDesirableIntType(
X->getType()->getScalarSizeInBits()))
1611 bool TrueIfSigned =
false;
1628 if (
Xor->hasOneUse()) {
1630 if (!Cmp.isEquality() && XorC->
isSignMask()) {
1631 Pred = Cmp.getFlippedSignednessPredicate();
1632 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(),
C ^ *XorC));
1637 Pred = Cmp.getFlippedSignednessPredicate();
1638 Pred = Cmp.getSwappedPredicate(Pred);
1639 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(),
C ^ *XorC));
1646 if (*XorC == ~
C && (
C + 1).isPowerOf2())
1649 if (*XorC ==
C && (
C + 1).isPowerOf2())
1654 if (*XorC == -
C &&
C.isPowerOf2())
1656 ConstantInt::get(
X->getType(), ~
C));
1658 if (*XorC ==
C && (-
C).isPowerOf2())
1660 ConstantInt::get(
X->getType(), ~
C));
1682 const APInt *ShiftC;
1687 Type *XType =
X->getType();
1693 return new ICmpInst(Pred,
Add, ConstantInt::get(XType, Bound));
1702 if (!Shift || !Shift->
isShift())
1710 unsigned ShiftOpcode = Shift->
getOpcode();
1711 bool IsShl = ShiftOpcode == Instruction::Shl;
1714 APInt NewAndCst, NewCmpCst;
1715 bool AnyCmpCstBitsShiftedOut;
1716 if (ShiftOpcode == Instruction::Shl) {
1724 NewCmpCst = C1.
lshr(*C3);
1725 NewAndCst = C2.
lshr(*C3);
1726 AnyCmpCstBitsShiftedOut = NewCmpCst.
shl(*C3) != C1;
1727 }
else if (ShiftOpcode == Instruction::LShr) {
1732 NewCmpCst = C1.
shl(*C3);
1733 NewAndCst = C2.
shl(*C3);
1734 AnyCmpCstBitsShiftedOut = NewCmpCst.
lshr(*C3) != C1;
1740 assert(ShiftOpcode == Instruction::AShr &&
"Unknown shift opcode");
1741 NewCmpCst = C1.
shl(*C3);
1742 NewAndCst = C2.
shl(*C3);
1743 AnyCmpCstBitsShiftedOut = NewCmpCst.
ashr(*C3) != C1;
1744 if (NewAndCst.
ashr(*C3) != C2)
1748 if (AnyCmpCstBitsShiftedOut) {
1758 Shift->
getOperand(0), ConstantInt::get(
And->getType(), NewAndCst));
1759 return new ICmpInst(Cmp.getPredicate(), NewAnd,
1760 ConstantInt::get(
And->getType(), NewCmpCst));
1777 return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
1791 return new TruncInst(
And->getOperand(0), Cmp.getType());
1802 ConstantInt::get(
X->getType(), ~*C2));
1807 ConstantInt::get(
X->getType(), -*C2));
1810 if (!
And->hasOneUse())
1813 if (Cmp.isEquality() && C1.
isZero()) {
1831 Constant *NegBOC = ConstantInt::get(
And->getType(), -NewC2);
1833 return new ICmpInst(NewPred,
X, NegBOC);
1851 if (!Cmp.getType()->isVectorTy()) {
1852 Type *WideType = W->getType();
1854 Constant *ZextC1 = ConstantInt::get(WideType, C1.
zext(WideScalarBits));
1855 Constant *ZextC2 = ConstantInt::get(WideType, C2->
zext(WideScalarBits));
1857 return new ICmpInst(Cmp.getPredicate(), NewAnd, ZextC1);
1868 if (!Cmp.isSigned() && C1.
isZero() &&
And->getOperand(0)->hasOneUse() &&
1875 unsigned UsesRemoved = 0;
1876 if (
And->hasOneUse())
1878 if (
Or->hasOneUse())
1885 if (UsesRemoved >= RequireUsesRemoved) {
1889 One,
Or->getName());
1891 return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
1905 if (!Cmp.getParent()->getParent()->hasFnAttribute(
1906 Attribute::NoImplicitFloat) &&
1909 Type *FPType = V->getType()->getScalarType();
1910 if (FPType->isIEEELikeFPTy() && (C1.
isZero() || C1 == *C2)) {
1911 APInt ExponentMask =
1913 if (*C2 == ExponentMask) {
1914 unsigned Mask = C1.
isZero()
1948 Constant *MinSignedC = ConstantInt::get(
1952 return new ICmpInst(NewPred,
X, MinSignedC);
1967 if (!Cmp.isEquality())
1973 if (Cmp.getOperand(1) ==
Y &&
C.isNegatedPowerOf2()) {
1984 X->getType()->isIntOrIntVectorTy(1) && (
C.isZero() ||
C.isOne())) {
1990 return BinaryOperator::CreateAnd(TruncY,
X);
2008 const APInt *Addend, *Msk;
2012 APInt NewComperand = (
C - *Addend) & *Msk;
2013 Value *MaskA =
Builder.CreateAnd(
A, ConstantInt::get(
A->getType(), *Msk));
2015 ConstantInt::get(MaskA->
getType(), NewComperand));
2037 while (!WorkList.
empty()) {
2038 auto MatchOrOperatorArgument = [&](
Value *OrOperatorArgument) {
2041 if (
match(OrOperatorArgument,
2047 if (
match(OrOperatorArgument,
2057 Value *OrOperatorLhs, *OrOperatorRhs;
2059 if (!
match(CurrentValue,
2064 MatchOrOperatorArgument(OrOperatorRhs);
2065 MatchOrOperatorArgument(OrOperatorLhs);
2070 Value *LhsCmp = Builder.CreateICmp(Pred, CmpValues.
rbegin()->first,
2071 CmpValues.
rbegin()->second);
2073 for (
auto It = CmpValues.
rbegin() + 1; It != CmpValues.
rend(); ++It) {
2074 Value *RhsCmp = Builder.CreateICmp(Pred, It->first, It->second);
2075 LhsCmp = Builder.CreateBinOp(BOpc, LhsCmp, RhsCmp);
2091 ConstantInt::get(V->getType(), 1));
2094 Value *OrOp0 =
Or->getOperand(0), *OrOp1 =
Or->getOperand(1);
2101 Builder.CreateXor(OrOp1, ConstantInt::get(OrOp1->getType(),
C));
2102 return new ICmpInst(Pred, OrOp0, NewC);
2106 if (
match(OrOp1,
m_APInt(MaskC)) && Cmp.isEquality()) {
2107 if (*MaskC ==
C && (
C + 1).isPowerOf2()) {
2112 return new ICmpInst(Pred, OrOp0, OrOp1);
2119 if (
Or->hasOneUse()) {
2121 Constant *NewC = ConstantInt::get(
Or->getType(),
C ^ (*MaskC));
2133 Constant *NewC = ConstantInt::get(
X->getType(), TrueIfSigned ? 1 : 0);
2161 if (!Cmp.isEquality() || !
C.isZero() || !
Or->hasOneUse())
2193 if (Cmp.isEquality() &&
C.isZero() &&
X ==
Mul->getOperand(1) &&
2194 (
Mul->hasNoUnsignedWrap() ||
Mul->hasNoSignedWrap()))
2216 if (Cmp.isEquality()) {
2218 if (
Mul->hasNoSignedWrap() &&
C.srem(*MulC).isZero()) {
2219 Constant *NewC = ConstantInt::get(MulTy,
C.sdiv(*MulC));
2227 if (
C.urem(*MulC).isZero()) {
2230 if ((*MulC & 1).isOne() ||
Mul->hasNoUnsignedWrap()) {
2231 Constant *NewC = ConstantInt::get(MulTy,
C.udiv(*MulC));
2244 if (
C.isMinSignedValue() && MulC->
isAllOnes())
2250 NewC = ConstantInt::get(
2254 "Unexpected predicate");
2255 NewC = ConstantInt::get(
2260 NewC = ConstantInt::get(
2264 "Unexpected predicate");
2265 NewC = ConstantInt::get(
2270 return NewC ?
new ICmpInst(Pred,
X, NewC) :
nullptr;
2282 unsigned TypeBits =
C.getBitWidth();
2284 if (Cmp.isUnsigned()) {
2304 return new ICmpInst(Pred,
Y, ConstantInt::get(ShiftType, CLog2));
2305 }
else if (Cmp.isSigned() && C2->
isOne()) {
2306 Constant *BitWidthMinusOne = ConstantInt::get(ShiftType, TypeBits - 1);
2327 const APInt *ShiftVal;
2357 const APInt *ShiftAmt;
2363 unsigned TypeBits =
C.getBitWidth();
2364 if (ShiftAmt->
uge(TypeBits))
2376 APInt ShiftedC =
C.ashr(*ShiftAmt);
2377 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2380 C.ashr(*ShiftAmt).shl(*ShiftAmt) ==
C) {
2381 APInt ShiftedC =
C.ashr(*ShiftAmt);
2382 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2389 assert(!
C.isMinSignedValue() &&
"Unexpected icmp slt");
2390 APInt ShiftedC = (
C - 1).ashr(*ShiftAmt) + 1;
2391 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2401 APInt ShiftedC =
C.lshr(*ShiftAmt);
2402 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2405 C.lshr(*ShiftAmt).shl(*ShiftAmt) ==
C) {
2406 APInt ShiftedC =
C.lshr(*ShiftAmt);
2407 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2414 assert(
C.ugt(0) &&
"ult 0 should have been eliminated");
2415 APInt ShiftedC = (
C - 1).lshr(*ShiftAmt) + 1;
2416 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2420 if (Cmp.isEquality() && Shl->
hasOneUse()) {
2426 Constant *LShrC = ConstantInt::get(ShType,
C.lshr(*ShiftAmt));
2431 bool TrueIfSigned =
false;
2443 if (Cmp.isUnsigned() && Shl->
hasOneUse()) {
2445 if ((
C + 1).isPowerOf2() &&
2453 if (
C.isPowerOf2() &&
2483 Pred, ConstantInt::get(ShType->
getContext(),
C))) {
2484 CmpPred = FlippedStrictness->first;
2492 ConstantInt::get(TruncTy, RHSC.
ashr(*ShiftAmt).
trunc(TypeBits - Amt));
2494 Builder.CreateTrunc(
X, TruncTy,
"",
false,
2511 if (Cmp.isEquality() && Shr->
isExact() &&
C.isZero())
2512 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
2514 bool IsAShr = Shr->
getOpcode() == Instruction::AShr;
2515 const APInt *ShiftValC;
2517 if (Cmp.isEquality())
2535 assert(ShiftValC->
uge(
C) &&
"Expected simplify of compare");
2536 assert((IsUGT || !
C.isZero()) &&
"Expected X u< 0 to simplify");
2538 unsigned CmpLZ = IsUGT ?
C.countl_zero() : (
C - 1).
countl_zero();
2546 const APInt *ShiftAmtC;
2552 unsigned TypeBits =
C.getBitWidth();
2554 if (ShAmtVal >= TypeBits || ShAmtVal == 0)
2557 bool IsExact = Shr->
isExact();
2565 (
C - 1).isPowerOf2() &&
C.countLeadingZeros() > ShAmtVal) {
2571 APInt ShiftedC = (
C - 1).shl(ShAmtVal) + 1;
2572 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2578 APInt ShiftedC =
C.shl(ShAmtVal);
2579 if (ShiftedC.
ashr(ShAmtVal) ==
C)
2580 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2584 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2585 if (!
C.isMaxSignedValue() && !(
C + 1).shl(ShAmtVal).isMinSignedValue() &&
2586 (ShiftedC + 1).ashr(ShAmtVal) == (
C + 1))
2587 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2593 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2594 if ((ShiftedC + 1).ashr(ShAmtVal) == (
C + 1) ||
2595 (
C + 1).shl(ShAmtVal).isMinSignedValue())
2596 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2603 if (
C.getBitWidth() > 2 &&
C.getNumSignBits() <= ShAmtVal) {
2613 }
else if (!IsAShr) {
2617 APInt ShiftedC =
C.shl(ShAmtVal);
2618 if (ShiftedC.
lshr(ShAmtVal) ==
C)
2619 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2623 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2624 if ((ShiftedC + 1).lshr(ShAmtVal) == (
C + 1))
2625 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2629 if (!Cmp.isEquality())
2637 assert(((IsAShr &&
C.shl(ShAmtVal).ashr(ShAmtVal) ==
C) ||
2638 (!IsAShr &&
C.shl(ShAmtVal).lshr(ShAmtVal) ==
C)) &&
2639 "Expected icmp+shr simplify did not occur.");
2644 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy,
C << ShAmtVal));
2650 Constant *Mask = ConstantInt::get(ShrTy, Val);
2652 return new ICmpInst(Pred,
And, ConstantInt::get(ShrTy,
C << ShAmtVal));
2669 const APInt *DivisorC;
2678 "ult X, 0 should have been simplified already.");
2683 if (!NormalizedC.
uge(DivisorC->
abs() - 1))
2706 const APInt *DivisorC;
2715 !
C.isStrictlyPositive()))
2721 Constant *MaskC = ConstantInt::get(Ty, SignMask | (*DivisorC - 1));
2725 return new ICmpInst(Pred,
And, ConstantInt::get(Ty,
C));
2752 assert(*C2 != 0 &&
"udiv 0, X should have been simplified already.");
2757 "icmp ugt X, UINT_MAX should have been simplified already.");
2759 ConstantInt::get(Ty, C2->
udiv(
C + 1)));
2764 assert(
C != 0 &&
"icmp ult X, 0 should have been simplified already.");
2766 ConstantInt::get(Ty, C2->
udiv(
C)));
2780 bool DivIsSigned = Div->
getOpcode() == Instruction::SDiv;
2790 if (Cmp.isEquality() && Div->
hasOneUse() &&
C.isSignBitSet() &&
2791 (!DivIsSigned ||
C.isMinSignedValue())) {
2792 Value *XBig =
Builder.CreateICmp(Pred,
X, ConstantInt::get(Ty,
C));
2793 Value *YOne =
Builder.CreateICmp(Pred,
Y, ConstantInt::get(Ty, 1));
2816 if (!Cmp.isEquality() && DivIsSigned != Cmp.isSigned())
2835 bool ProdOV = (DivIsSigned ? Prod.
sdiv(*C2) : Prod.
udiv(*C2)) !=
C;
2848 int LoOverflow = 0, HiOverflow = 0;
2849 APInt LoBound, HiBound;
2854 HiOverflow = LoOverflow = ProdOV;
2863 LoBound = -(RangeSize - 1);
2864 HiBound = RangeSize;
2865 }
else if (
C.isStrictlyPositive()) {
2867 HiOverflow = LoOverflow = ProdOV;
2873 LoOverflow = HiOverflow = ProdOV ? -1 : 0;
2875 APInt DivNeg = -RangeSize;
2876 LoOverflow =
addWithOverflow(LoBound, HiBound, DivNeg,
true) ? -1 : 0;
2884 LoBound = RangeSize + 1;
2885 HiBound = -RangeSize;
2886 if (HiBound == *C2) {
2890 }
else if (
C.isStrictlyPositive()) {
2893 HiOverflow = LoOverflow = ProdOV ? -1 : 0;
2899 LoOverflow = HiOverflow = ProdOV;
2912 if (LoOverflow && HiOverflow)
2916 X, ConstantInt::get(Ty, LoBound));
2919 X, ConstantInt::get(Ty, HiBound));
2923 if (LoOverflow && HiOverflow)
2927 X, ConstantInt::get(Ty, LoBound));
2930 X, ConstantInt::get(Ty, HiBound));
2935 if (LoOverflow == +1)
2937 if (LoOverflow == -1)
2939 return new ICmpInst(Pred,
X, ConstantInt::get(Ty, LoBound));
2942 if (HiOverflow == +1)
2944 if (HiOverflow == -1)
2974 bool HasNSW =
Sub->hasNoSignedWrap();
2975 bool HasNUW =
Sub->hasNoUnsignedWrap();
2977 ((Cmp.isUnsigned() && HasNUW) || (Cmp.isSigned() && HasNSW)) &&
2979 return new ICmpInst(SwappedPred,
Y, ConstantInt::get(Ty, SubResult));
2987 if (Cmp.isEquality() &&
C.isZero() &&
2988 none_of((
Sub->users()), [](
const User *U) { return isa<PHINode>(U); }))
2996 if (!
Sub->hasOneUse())
2999 if (
Sub->hasNoSignedWrap()) {
3023 (*C2 & (
C - 1)) == (
C - 1))
3036 return new ICmpInst(SwappedPred,
Add, ConstantInt::get(Ty, ~
C));
3042 auto FoldConstant = [&](
bool Val) {
3043 Constant *Res = Val ? Builder.getTrue() : Builder.getFalse();
3050 switch (Table.to_ulong()) {
3052 return FoldConstant(
false);
3054 return HasOneUse ? Builder.CreateNot(Builder.CreateOr(Op0, Op1)) :
nullptr;
3056 return HasOneUse ? Builder.CreateAnd(Builder.CreateNot(Op0), Op1) :
nullptr;
3058 return Builder.CreateNot(Op0);
3060 return HasOneUse ? Builder.CreateAnd(Op0, Builder.CreateNot(Op1)) :
nullptr;
3062 return Builder.CreateNot(Op1);
3064 return Builder.CreateXor(Op0, Op1);
3066 return HasOneUse ? Builder.CreateNot(Builder.CreateAnd(Op0, Op1)) :
nullptr;
3068 return Builder.CreateAnd(Op0, Op1);
3070 return HasOneUse ? Builder.CreateNot(Builder.CreateXor(Op0, Op1)) :
nullptr;
3074 return HasOneUse ? Builder.CreateOr(Builder.CreateNot(Op0), Op1) :
nullptr;
3078 return HasOneUse ? Builder.CreateOr(Op0, Builder.CreateNot(Op1)) :
nullptr;
3080 return Builder.CreateOr(Op0, Op1);
3082 return FoldConstant(
true);
3098 Type *Ty = V->getType();
3100 Cond->getType()->isIntOrIntVectorTy(1)) {
3101 TrueC = ConstantInt::get(Ty, 1);
3102 FalseC = ConstantInt::get(Ty, 0);
3106 Cond->getType()->isIntOrIntVectorTy(1)) {
3107 FalseC = ConstantInt::get(Ty, 0);
3120 Cmp.getType() !=
A->getType() || Cmp.getType() !=
B->getType())
3123 std::bitset<4> Table;
3124 auto ComputeTable = [&](
bool First,
bool Second) -> std::optional<bool> {
3128 auto *Val = Res->getType()->isVectorTy() ? Res->getSplatValue() : Res;
3132 return std::nullopt;
3135 for (
unsigned I = 0;
I < 4; ++
I) {
3136 bool First = (
I >> 1) & 1;
3137 bool Second =
I & 1;
3138 if (
auto Res = ComputeTable(
First, Second))
3160 const APInt *ShAmtC;
3168 return new ICmpInst(Pred,
A, ConstantInt::get(
A->getType(),
C));
3180 if (
Add->hasNoUnsignedWrap() &&
3183 APInt NewC =
C.usub_ov(*C2, Overflow);
3187 return new ICmpInst(Pred,
X, ConstantInt::get(Ty, NewC));
3192 if (
Add->hasNoSignedWrap() &&
3195 APInt NewC =
C.ssub_ov(*C2, Overflow);
3199 return new ICmpInst(ChosenPred,
X, ConstantInt::get(Ty, NewC));
3203 C.isNonNegative() && (
C - *C2).isNonNegative() &&
3206 ConstantInt::get(Ty,
C - *C2));
3211 if (Cmp.isSigned()) {
3212 if (
Lower.isSignMask())
3214 if (
Upper.isSignMask())
3217 if (
Lower.isMinValue())
3219 if (
Upper.isMinValue())
3252 if (!
Add->hasOneUse())
3267 ConstantInt::get(Ty,
C * 2));
3281 Builder.CreateAdd(
X, ConstantInt::get(Ty, *C2 -
C - 1)),
3282 ConstantInt::get(Ty, ~
C));
3287 Type *NewCmpTy = V->getType();
3289 if (shouldChangeType(Ty, NewCmpTy)) {
3300 :
Builder.CreateAdd(V, ConstantInt::get(NewCmpTy, EquivOffset)),
3301 ConstantInt::get(NewCmpTy, EquivInt));
3323 Value *EqualVal =
SI->getTrueValue();
3324 Value *UnequalVal =
SI->getFalseValue();
3347 auto FlippedStrictness =
3349 if (!FlippedStrictness)
3352 "basic correctness failure");
3353 RHS2 = FlippedStrictness->second;
3365 assert(
C &&
"Cmp RHS should be a constant int!");
3371 Value *OrigLHS, *OrigRHS;
3372 ConstantInt *C1LessThan, *C2Equal, *C3GreaterThan;
3373 if (Cmp.hasOneUse() &&
3376 assert(C1LessThan && C2Equal && C3GreaterThan);
3379 C1LessThan->
getValue(),
C->getValue(), Cmp.getPredicate());
3381 Cmp.getPredicate());
3383 C3GreaterThan->
getValue(),
C->getValue(), Cmp.getPredicate());
3394 if (TrueWhenLessThan)
3400 if (TrueWhenGreaterThan)
3415 Value *Op1 = Cmp.getOperand(1);
3416 Value *BCSrcOp = Bitcast->getOperand(0);
3417 Type *SrcType = Bitcast->getSrcTy();
3418 Type *DstType = Bitcast->getType();
3422 if (SrcType->isVectorTy() == DstType->isVectorTy() &&
3423 SrcType->getScalarSizeInBits() == DstType->getScalarSizeInBits()) {
3438 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(), 1));
3465 Type *XType =
X->getType();
3468 if (!(XType->
isPPC_FP128Ty() || SrcType->isPPC_FP128Ty())) {
3483 Type *FPType = SrcType->getScalarType();
3484 if (!Cmp.getParent()->getParent()->hasFnAttribute(
3485 Attribute::NoImplicitFloat) &&
3486 Cmp.isEquality() && FPType->isIEEELikeFPTy()) {
3492 Builder.createIsFPClass(BCSrcOp, Mask));
3499 if (!
match(Cmp.getOperand(1),
m_APInt(
C)) || !DstType->isIntegerTy() ||
3500 !SrcType->isIntOrIntVectorTy())
3510 if (Cmp.isEquality() &&
C->isAllOnes() && Bitcast->hasOneUse()) {
3511 if (
Value *NotBCSrcOp =
3513 Value *Cast =
Builder.CreateBitCast(NotBCSrcOp, DstType);
3522 if (Cmp.isEquality() &&
C->isZero() && Bitcast->hasOneUse() &&
3525 Type *NewType =
Builder.getIntNTy(VecTy->getPrimitiveSizeInBits());
3545 if (
C->isSplat(EltTy->getBitWidth())) {
3552 Value *Extract =
Builder.CreateExtractElement(Vec, Elem);
3553 Value *NewC = ConstantInt::get(EltTy,
C->trunc(EltTy->getBitWidth()));
3554 return new ICmpInst(Pred, Extract, NewC);
3590 Value *Cmp0 = Cmp.getOperand(0);
3592 if (
C->isZero() && Cmp.isEquality() && Cmp0->
hasOneUse() &&
3599 return new ICmpInst(Cmp.getPredicate(),
X,
Y);
3614 if (!Cmp.isEquality())
3623 case Instruction::SRem:
3634 case Instruction::Add: {
3641 }
else if (
C.isZero()) {
3644 if (
Value *NegVal = dyn_castNegVal(BOp1))
3645 return new ICmpInst(Pred, BOp0, NegVal);
3646 if (
Value *NegVal = dyn_castNegVal(BOp0))
3647 return new ICmpInst(Pred, NegVal, BOp1);
3656 return new ICmpInst(Pred, BOp0, Neg);
3661 case Instruction::Xor:
3666 }
else if (
C.isZero()) {
3668 return new ICmpInst(Pred, BOp0, BOp1);
3671 case Instruction::Or: {
3692 Cond->getType() == Cmp.getType()) {
3730 case Instruction::UDiv:
3731 case Instruction::SDiv:
3741 return new ICmpInst(Pred, BOp0, BOp1);
3744 Instruction::Mul, BO->
getOpcode() == Instruction::SDiv, BOp1,
3745 Cmp.getOperand(1), BO);
3749 return new ICmpInst(Pred, YC, BOp0);
3753 if (BO->
getOpcode() == Instruction::UDiv &&
C.isZero()) {
3756 return new ICmpInst(NewPred, BOp1, BOp0);
3770 "Non-ctpop intrin in ctpop fold");
3805 Type *Ty =
II->getType();
3809 switch (
II->getIntrinsicID()) {
3810 case Intrinsic::abs:
3813 if (
C.isZero() ||
C.isMinSignedValue())
3814 return new ICmpInst(Pred,
II->getArgOperand(0), ConstantInt::get(Ty,
C));
3817 case Intrinsic::bswap:
3819 return new ICmpInst(Pred,
II->getArgOperand(0),
3820 ConstantInt::get(Ty,
C.byteSwap()));
3822 case Intrinsic::bitreverse:
3824 return new ICmpInst(Pred,
II->getArgOperand(0),
3825 ConstantInt::get(Ty,
C.reverseBits()));
3827 case Intrinsic::ctlz:
3828 case Intrinsic::cttz: {
3831 return new ICmpInst(Pred,
II->getArgOperand(0),
3837 unsigned Num =
C.getLimitedValue(
BitWidth);
3839 bool IsTrailing =
II->getIntrinsicID() == Intrinsic::cttz;
3842 APInt Mask2 = IsTrailing
3846 ConstantInt::get(Ty, Mask2));
3851 case Intrinsic::ctpop: {
3854 bool IsZero =
C.isZero();
3856 return new ICmpInst(Pred,
II->getArgOperand(0),
3863 case Intrinsic::fshl:
3864 case Intrinsic::fshr:
3865 if (
II->getArgOperand(0) ==
II->getArgOperand(1)) {
3866 const APInt *RotAmtC;
3870 return new ICmpInst(Pred,
II->getArgOperand(0),
3871 II->getIntrinsicID() == Intrinsic::fshl
3872 ? ConstantInt::get(Ty,
C.rotr(*RotAmtC))
3873 : ConstantInt::get(Ty,
C.rotl(*RotAmtC)));
3877 case Intrinsic::umax:
3878 case Intrinsic::uadd_sat: {
3881 if (
C.isZero() &&
II->hasOneUse()) {
3888 case Intrinsic::ssub_sat:
3893 if (
C.isZero() &&
II->getType()->getScalarSizeInBits() > 1)
3894 return new ICmpInst(Pred,
II->getArgOperand(0),
II->getArgOperand(1));
3896 case Intrinsic::usub_sat: {
3901 return new ICmpInst(NewPred,
II->getArgOperand(0),
II->getArgOperand(1));
3916 assert(Cmp.isEquality());
3919 Value *Op0 = Cmp.getOperand(0);
3920 Value *Op1 = Cmp.getOperand(1);
3923 if (!IIOp0 || !IIOp1 || IIOp0->getIntrinsicID() != IIOp1->getIntrinsicID())
3926 switch (IIOp0->getIntrinsicID()) {
3927 case Intrinsic::bswap:
3928 case Intrinsic::bitreverse:
3931 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
3932 case Intrinsic::fshl:
3933 case Intrinsic::fshr: {
3936 if (IIOp0->getOperand(0) != IIOp0->getOperand(1))
3938 if (IIOp1->getOperand(0) != IIOp1->getOperand(1))
3940 if (IIOp0->getOperand(2) == IIOp1->getOperand(2))
3941 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
3947 unsigned OneUses = IIOp0->hasOneUse() + IIOp1->hasOneUse();
3952 Builder.CreateSub(IIOp0->getOperand(2), IIOp1->getOperand(2));
3953 Value *CombinedRotate = Builder.CreateIntrinsic(
3954 Op0->
getType(), IIOp0->getIntrinsicID(),
3955 {IIOp0->getOperand(0), IIOp0->getOperand(0), SubAmt});
3956 return new ICmpInst(Pred, IIOp1->getOperand(0), CombinedRotate);
3974 switch (
II->getIntrinsicID()) {
3977 case Intrinsic::fshl:
3978 case Intrinsic::fshr:
3979 if (Cmp.isEquality() &&
II->getArgOperand(0) ==
II->getArgOperand(1)) {
3981 if (
C.isZero() ||
C.isAllOnes())
3982 return new ICmpInst(Pred,
II->getArgOperand(0), Cmp.getOperand(1));
3996 case Instruction::Xor:
4000 case Instruction::And:
4004 case Instruction::Or:
4008 case Instruction::Mul:
4012 case Instruction::Shl:
4016 case Instruction::LShr:
4017 case Instruction::AShr:
4021 case Instruction::SRem:
4025 case Instruction::UDiv:
4029 case Instruction::SDiv:
4033 case Instruction::Sub:
4037 case Instruction::Add:
4061 if (!
II->hasOneUse())
4077 Value *Op0 =
II->getOperand(0);
4078 Value *Op1 =
II->getOperand(1);
4087 switch (
II->getIntrinsicID()) {
4090 "This function only works with usub_sat and uadd_sat for now!");
4091 case Intrinsic::uadd_sat:
4094 case Intrinsic::usub_sat:
4104 II->getBinaryOp(), *COp1,
II->getNoWrapKind());
4111 if (
II->getBinaryOp() == Instruction::Add)
4117 SatValCheck ? Instruction::BinaryOps::Or : Instruction::BinaryOps::And;
4119 std::optional<ConstantRange> Combination;
4120 if (CombiningOp == Instruction::BinaryOps::Or)
4132 Combination->getEquivalentICmp(EquivPred, EquivInt, EquivOffset);
4136 Builder.CreateAdd(Op0, ConstantInt::get(Op1->
getType(), EquivOffset)),
4137 ConstantInt::get(Op1->
getType(), EquivInt));
4144 std::optional<ICmpInst::Predicate> NewPredicate = std::nullopt;
4149 NewPredicate = Pred;
4153 else if (
C.isAllOnes())
4161 else if (
C.isZero())
4178 if (!
C.isZero() && !
C.isAllOnes())
4189 if (
I->getIntrinsicID() == Intrinsic::scmp)
4203 switch (
II->getIntrinsicID()) {
4206 case Intrinsic::uadd_sat:
4207 case Intrinsic::usub_sat:
4212 case Intrinsic::ctpop: {
4217 case Intrinsic::scmp:
4218 case Intrinsic::ucmp:
4224 if (Cmp.isEquality())
4227 Type *Ty =
II->getType();
4229 switch (
II->getIntrinsicID()) {
4230 case Intrinsic::ctpop: {
4242 case Intrinsic::ctlz: {
4245 unsigned Num =
C.getLimitedValue();
4248 II->getArgOperand(0), ConstantInt::get(Ty, Limit));
4253 unsigned Num =
C.getLimitedValue();
4256 II->getArgOperand(0), ConstantInt::get(Ty, Limit));
4260 case Intrinsic::cttz: {
4262 if (!
II->hasOneUse())
4269 Builder.CreateAnd(
II->getArgOperand(0), Mask),
4277 Builder.CreateAnd(
II->getArgOperand(0), Mask),
4282 case Intrinsic::ssub_sat:
4289 return new ICmpInst(Pred,
II->getArgOperand(0),
II->getArgOperand(1));
4293 II->getArgOperand(1));
4297 II->getArgOperand(1));
4300 case Intrinsic::abs: {
4301 if (!
II->hasOneUse())
4305 bool IsIntMinPoison =
4312 Builder.CreateAdd(
X, ConstantInt::get(Ty,
C)),
4313 ConstantInt::get(Ty, 2 *
C));
4320 Builder.CreateAdd(
X, ConstantInt::get(Ty,
C - 1)),
4321 ConstantInt::get(Ty, 2 * (
C - 1)));
4335 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
4342 case Instruction::IntToPtr:
4351 case Instruction::Load:
4368 auto SimplifyOp = [&](
Value *
Op,
bool SelectCondIsTrue) ->
Value * {
4372 SI->getCondition(), Pred,
Op, RHS,
DL, SelectCondIsTrue))
4373 return ConstantInt::get(
I.getType(), *Impl);
4378 Value *Op1 = SimplifyOp(
SI->getOperand(1),
true);
4382 Value *Op2 = SimplifyOp(
SI->getOperand(2),
false);
4386 auto Simplifies = [&](
Value *
Op,
unsigned Idx) {
4401 bool Transform =
false;
4404 else if (Simplifies(Op1, 1) || Simplifies(Op2, 2)) {
4406 if (
SI->hasOneUse())
4409 else if (CI && !CI->
isZero())
4417 Op1 =
Builder.CreateICmp(Pred,
SI->getOperand(1), RHS,
I.getName());
4419 Op2 =
Builder.CreateICmp(Pred,
SI->getOperand(2), RHS,
I.getName());
4429 unsigned Depth = 0) {
4432 if (V->getType()->getScalarSizeInBits() == 1)
4440 switch (
I->getOpcode()) {
4441 case Instruction::ZExt:
4444 case Instruction::SExt:
4448 case Instruction::And:
4449 case Instruction::Or:
4456 case Instruction::Xor:
4466 case Instruction::Select:
4470 case Instruction::Shl:
4473 case Instruction::LShr:
4476 case Instruction::AShr:
4480 case Instruction::Add:
4486 case Instruction::Sub:
4492 case Instruction::Call: {
4494 switch (
II->getIntrinsicID()) {
4497 case Intrinsic::umax:
4498 case Intrinsic::smax:
4499 case Intrinsic::umin:
4500 case Intrinsic::smin:
4505 case Intrinsic::bitreverse:
4595 auto IsLowBitMask = [&]() {
4613 auto Check = [&]() {
4631 auto Check = [&]() {
4650 if (!IsLowBitMask())
4669 const APInt *C0, *C1;
4686 const APInt &MaskedBits = *C0;
4687 assert(MaskedBits != 0 &&
"shift by zero should be folded away already.");
4708 auto *XType =
X->getType();
4709 const unsigned XBitWidth = XType->getScalarSizeInBits();
4711 assert(
BitWidth.ugt(MaskedBits) &&
"shifts should leave some bits untouched");
4724 Value *T0 = Builder.CreateAdd(
X, ConstantInt::get(XType, AddCst));
4726 Value *
T1 = Builder.CreateICmp(DstPred, T0, ConstantInt::get(XType, ICmpCst));
4742 !
I.getOperand(0)->hasOneUse())
4767 assert(NarrowestTy ==
I.getOperand(0)->getType() &&
4768 "We did not look past any shifts while matching XShift though.");
4769 bool HadTrunc = WidestTy !=
I.getOperand(0)->getType();
4776 auto XShiftOpcode = XShift->
getOpcode();
4777 if (XShiftOpcode == YShift->
getOpcode())
4780 Value *
X, *XShAmt, *
Y, *YShAmt;
4789 if (!
match(
I.getOperand(0),
4815 unsigned MaximalPossibleTotalShiftAmount =
4818 APInt MaximalRepresentableShiftAmount =
4820 if (MaximalRepresentableShiftAmount.
ult(MaximalPossibleTotalShiftAmount))
4829 if (NewShAmt->getType() != WidestTy) {
4839 if (!
match(NewShAmt,
4841 APInt(WidestBitWidth, WidestBitWidth))))
4846 auto CanFold = [NewShAmt, WidestBitWidth, NarrowestShift, SQ,
4852 ? NewShAmt->getSplatValue()
4855 if (NewShAmtSplat &&
4865 unsigned MaxActiveBits = Known.
getBitWidth() - MinLeadZero;
4866 if (MaxActiveBits <= 1)
4876 unsigned MaxActiveBits = Known.
getBitWidth() - MinLeadZero;
4877 if (MaxActiveBits <= 1)
4880 if (NewShAmtSplat) {
4883 if (AdjNewShAmt.
ule(MinLeadZero))
4894 X = Builder.CreateZExt(
X, WidestTy);
4895 Y = Builder.CreateZExt(
Y, WidestTy);
4897 Value *T0 = XShiftOpcode == Instruction::BinaryOps::LShr
4898 ? Builder.CreateLShr(
X, NewShAmt)
4899 : Builder.CreateShl(
X, NewShAmt);
4900 Value *
T1 = Builder.CreateAnd(T0,
Y);
4901 return Builder.CreateICmp(
I.getPredicate(),
T1,
4919 if (!
I.isEquality() &&
4929 NeedNegation =
false;
4932 NeedNegation =
true;
4938 if (
I.isEquality() &&
4953 bool MulHadOtherUses =
Mul && !
Mul->hasOneUse();
4954 if (MulHadOtherUses)
4958 Div->
getOpcode() == Instruction::UDiv ? Intrinsic::umul_with_overflow
4959 : Intrinsic::smul_with_overflow,
4960 X->getType(), {X, Y},
nullptr,
"mul");
4965 if (MulHadOtherUses)
4970 Res =
Builder.CreateNot(Res,
"mul.not.ov");
4974 if (MulHadOtherUses)
5000 Type *Ty =
X->getType();
5004 Value *
And = Builder.CreateAnd(
X, MaxSignedVal);
5014 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5076 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5111 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5127 return new ICmpInst(PredOut, Op0, Op1);
5147 return new ICmpInst(NewPred, Op0, Const);
5159 if (!
C.isPowerOf2())
5172 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5240 return new ICmpInst(NewPred, Op1, Zero);
5249 return new ICmpInst(NewPred, Op0, Zero);
5253 bool NoOp0WrapProblem =
false, NoOp1WrapProblem =
false;
5254 bool Op0HasNUW =
false, Op1HasNUW =
false;
5255 bool Op0HasNSW =
false, Op1HasNSW =
false;
5259 bool &HasNSW,
bool &HasNUW) ->
bool {
5266 }
else if (BO.
getOpcode() == Instruction::Or) {
5274 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr;
5278 NoOp0WrapProblem = hasNoWrapProblem(*BO0, Pred, Op0HasNSW, Op0HasNUW);
5282 NoOp1WrapProblem = hasNoWrapProblem(*BO1, Pred, Op1HasNSW, Op1HasNUW);
5287 if ((
A == Op1 ||
B == Op1) && NoOp0WrapProblem)
5293 if ((
C == Op0 ||
D == Op0) && NoOp1WrapProblem)
5298 if (
A &&
C && (
A ==
C ||
A ==
D ||
B ==
C ||
B ==
D) && NoOp0WrapProblem &&
5306 }
else if (
A ==
D) {
5310 }
else if (
B ==
C) {
5327 bool IsNegative) ->
bool {
5328 const APInt *OffsetC;
5340 if (!
C.isStrictlyPositive())
5361 if (
A && NoOp0WrapProblem &&
5362 ShareCommonDivisor(
A, Op1,
B,
5373 if (
C && NoOp1WrapProblem &&
5374 ShareCommonDivisor(Op0,
C,
D,
5387 if (
A &&
C && NoOp0WrapProblem && NoOp1WrapProblem &&
5389 const APInt *AP1, *AP2;
5397 if (AP1Abs.
uge(AP2Abs)) {
5398 APInt Diff = *AP1 - *AP2;
5401 A, C3,
"", Op0HasNUW && Diff.
ule(*AP1), Op0HasNSW);
5404 APInt Diff = *AP2 - *AP1;
5407 C, C3,
"", Op1HasNUW && Diff.
ule(*AP2), Op1HasNSW);
5426 if (BO0 && BO0->
getOpcode() == Instruction::Sub) {
5430 if (BO1 && BO1->
getOpcode() == Instruction::Sub) {
5436 if (
A == Op1 && NoOp0WrapProblem)
5439 if (
C == Op0 && NoOp1WrapProblem)
5459 if (
B &&
D &&
B ==
D && NoOp0WrapProblem && NoOp1WrapProblem)
5463 if (
A &&
C &&
A ==
C && NoOp0WrapProblem && NoOp1WrapProblem)
5471 if (RHSC->isNotMinSignedValue())
5472 return new ICmpInst(
I.getSwappedPredicate(),
X,
5490 if (Op0HasNSW && Op1HasNSW) {
5497 SQ.getWithInstruction(&
I));
5502 SQ.getWithInstruction(&
I));
5503 if (GreaterThan &&
match(GreaterThan,
m_One()))
5510 if (((Op0HasNSW && Op1HasNSW) || (Op0HasNUW && Op1HasNUW)) &&
5522 if (NonZero && BO0 && BO1 && Op0HasNSW && Op1HasNSW)
5529 if (NonZero && BO0 && BO1 && Op0HasNUW && Op1HasNUW)
5540 else if (BO1 && BO1->
getOpcode() == Instruction::SRem &&
5570 case Instruction::Add:
5571 case Instruction::Sub:
5572 case Instruction::Xor: {
5579 if (
C->isSignMask()) {
5585 if (BO0->
getOpcode() == Instruction::Xor &&
C->isMaxSignedValue()) {
5587 NewPred =
I.getSwappedPredicate(NewPred);
5593 case Instruction::Mul: {
5594 if (!
I.isEquality())
5602 if (
unsigned TZs =
C->countr_zero()) {
5608 return new ICmpInst(Pred, And1, And2);
5613 case Instruction::UDiv:
5614 case Instruction::LShr:
5619 case Instruction::SDiv:
5625 case Instruction::AShr:
5630 case Instruction::Shl: {
5631 bool NUW = Op0HasNUW && Op1HasNUW;
5632 bool NSW = Op0HasNSW && Op1HasNSW;
5635 if (!NSW &&
I.isSigned())
5699 auto IsCondKnownTrue = [](
Value *Val) -> std::optional<bool> {
5701 return std::nullopt;
5706 return std::nullopt;
5712 Pred = Pred.dropSameSign();
5715 if (!CmpXZ.has_value() && !CmpYZ.has_value())
5717 if (!CmpXZ.has_value()) {
5723 if (CmpYZ.has_value())
5747 if (!MinMaxCmpXZ.has_value()) {
5755 if (!MinMaxCmpXZ.has_value())
5771 return FoldIntoCmpYZ();
5798 return FoldIntoCmpYZ();
5807 return FoldIntoCmpYZ();
5839 const APInt *
Lo =
nullptr, *
Hi =
nullptr;
5862 I,
Builder.CreateICmp(Pred,
X, ConstantInt::get(
X->getType(),
C)));
5868 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5872 if (
I.isEquality()) {
5907 Type *Ty =
A->getType();
5908 CallInst *CtPop = Builder.CreateUnaryIntrinsic(Intrinsic::ctpop,
A);
5910 ConstantInt::get(Ty, 2))
5912 ConstantInt::get(Ty, 1));
5919using OffsetOp = std::pair<Instruction::BinaryOps, Value *>;
5921 bool AllowRecursion) {
5927 case Instruction::Add:
5928 Offsets.emplace_back(Instruction::Sub, Inst->
getOperand(1));
5929 Offsets.emplace_back(Instruction::Sub, Inst->
getOperand(0));
5931 case Instruction::Sub:
5932 Offsets.emplace_back(Instruction::Add, Inst->
getOperand(1));
5934 case Instruction::Xor:
5935 Offsets.emplace_back(Instruction::Xor, Inst->
getOperand(1));
5936 Offsets.emplace_back(Instruction::Xor, Inst->
getOperand(0));
5938 case Instruction::Shl:
5940 Offsets.emplace_back(Instruction::AShr, Inst->
getOperand(1));
5942 Offsets.emplace_back(Instruction::LShr, Inst->
getOperand(1));
5944 case Instruction::Select:
5945 if (AllowRecursion) {
5980 return Builder.CreateSelect(
5993 assert(
I.isEquality() &&
"Expected an equality icmp");
5994 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6005 case Instruction::AShr: {
6006 const APInt *CV, *CRHS;
6008 CV->
ashr(*CRHS).
shl(*CRHS) == *CV) &&
6014 case Instruction::LShr: {
6015 const APInt *CV, *CRHS;
6017 CV->
lshr(*CRHS).
shl(*CRHS) == *CV) &&
6036 auto ApplyOffset = [&](
Value *V,
unsigned BinOpc,
6039 if (!Sel->hasOneUse())
6041 Value *TrueVal = ApplyOffsetImpl(Sel->getTrueValue(), BinOpc,
RHS);
6044 Value *FalseVal = ApplyOffsetImpl(Sel->getFalseValue(), BinOpc,
RHS);
6049 if (
Value *Simplified = ApplyOffsetImpl(V, BinOpc,
RHS))
6054 for (
auto [BinOp,
RHS] : OffsetOps) {
6055 auto BinOpc =
static_cast<unsigned>(BinOp);
6057 auto Op0Result = ApplyOffset(Op0, BinOpc,
RHS);
6058 if (!Op0Result.isValid())
6060 auto Op1Result = ApplyOffset(Op1, BinOpc,
RHS);
6061 if (!Op1Result.isValid())
6064 Value *NewLHS = Op0Result.materialize(Builder);
6065 Value *NewRHS = Op1Result.materialize(Builder);
6066 return new ICmpInst(
I.getPredicate(), NewLHS, NewRHS);
6073 if (!
I.isEquality())
6076 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6080 if (
A == Op1 ||
B == Op1) {
6081 Value *OtherVal =
A == Op1 ?
B :
A;
6109 Value *OtherVal =
A == Op0 ?
B :
A;
6116 Value *
X =
nullptr, *
Y =
nullptr, *Z =
nullptr;
6122 }
else if (
A ==
D) {
6126 }
else if (
B ==
C) {
6130 }
else if (
B ==
D) {
6140 const APInt *C0, *C1;
6142 (*C0 ^ *C1).isNegatedPowerOf2();
6148 int(Op0->
hasOneUse()) + int(Op1->hasOneUse()) +
6150 if (XorIsNegP2 || UseCnt >= 2) {
6153 Op1 =
Builder.CreateAnd(Op1, Z);
6173 (Op0->
hasOneUse() || Op1->hasOneUse())) {
6178 MaskC->
countr_one() ==
A->getType()->getScalarSizeInBits())
6184 const APInt *AP1, *AP2;
6193 if (ShAmt < TypeBits && ShAmt != 0) {
6198 return new ICmpInst(NewPred,
Xor, ConstantInt::get(
A->getType(), CmpVal));
6208 if (ShAmt < TypeBits && ShAmt != 0) {
6228 if (ShAmt < ASize) {
6251 A->getType()->getScalarSizeInBits() ==
BitWidth * 2 &&
6252 (
I.getOperand(0)->hasOneUse() ||
I.getOperand(1)->hasOneUse())) {
6257 Add, ConstantInt::get(
A->getType(),
C.shl(1)));
6284 Builder.CreateIntrinsic(Op0->
getType(), Intrinsic::fshl, {A, A, B}));
6299 std::optional<bool> IsZero = std::nullopt;
6341 Constant *
C = ConstantInt::get(Res->X->getType(), Res->C);
6345 unsigned SrcBits =
X->getType()->getScalarSizeInBits();
6347 if (
II->getIntrinsicID() == Intrinsic::cttz ||
6348 II->getIntrinsicID() == Intrinsic::ctlz) {
6349 unsigned MaxRet = SrcBits;
6375 bool IsSignedExt = CastOp0->getOpcode() == Instruction::SExt;
6376 bool IsSignedCmp = ICmp.
isSigned();
6384 if (IsZext0 != IsZext1) {
6389 if (ICmp.
isEquality() &&
X->getType()->isIntOrIntVectorTy(1) &&
6390 Y->getType()->isIntOrIntVectorTy(1))
6400 bool IsNonNeg0 = NonNegInst0 && NonNegInst0->hasNonNeg();
6401 bool IsNonNeg1 = NonNegInst1 && NonNegInst1->hasNonNeg();
6403 if ((IsZext0 && IsNonNeg0) || (IsZext1 && IsNonNeg1))
6410 Type *XTy =
X->getType(), *YTy =
Y->getType();
6417 IsSignedExt ? Instruction::SExt : Instruction::ZExt;
6419 X =
Builder.CreateCast(CastOpcode,
X, YTy);
6421 Y =
Builder.CreateCast(CastOpcode,
Y, XTy);
6433 if (IsSignedCmp && IsSignedExt)
6446 Type *SrcTy = CastOp0->getSrcTy();
6454 if (IsSignedExt && IsSignedCmp)
6485 Value *SimplifiedOp0 = simplifyIntToPtrRoundTripCast(ICmp.
getOperand(0));
6486 Value *SimplifiedOp1 = simplifyIntToPtrRoundTripCast(ICmp.
getOperand(1));
6487 if (SimplifiedOp0 || SimplifiedOp1)
6489 SimplifiedOp0 ? SimplifiedOp0 : ICmp.
getOperand(0),
6490 SimplifiedOp1 ? SimplifiedOp1 : ICmp.
getOperand(1));
6498 Value *Op0Src = CastOp0->getOperand(0);
6499 Type *SrcTy = CastOp0->getSrcTy();
6500 Type *DestTy = CastOp0->getDestTy();
6504 auto CompatibleSizes = [&](
Type *PtrTy,
Type *IntTy) {
6509 return DL.getPointerTypeSizeInBits(PtrTy) == IntTy->getIntegerBitWidth();
6511 if (CastOp0->getOpcode() == Instruction::PtrToInt &&
6512 CompatibleSizes(SrcTy, DestTy)) {
6513 Value *NewOp1 =
nullptr;
6515 Value *PtrSrc = PtrToIntOp1->getOperand(0);
6517 NewOp1 = PtrToIntOp1->getOperand(0);
6527 if (CastOp0->getOpcode() == Instruction::IntToPtr &&
6528 CompatibleSizes(DestTy, SrcTy)) {
6529 Value *NewOp1 =
nullptr;
6531 Value *IntSrc = IntToPtrOp1->getOperand(0);
6533 NewOp1 = IntToPtrOp1->getOperand(0);
6553 case Instruction::Add:
6554 case Instruction::Sub:
6556 case Instruction::Mul:
6557 return !(
RHS->getType()->isIntOrIntVectorTy(1) && IsSigned) &&
6569 case Instruction::Add:
6574 case Instruction::Sub:
6579 case Instruction::Mul:
6588 bool IsSigned,
Value *LHS,
6599 Builder.SetInsertPoint(&OrigI);
6616 Result = Builder.CreateBinOp(BinaryOp,
LHS,
RHS);
6617 Result->takeName(&OrigI);
6621 Result = Builder.CreateBinOp(BinaryOp,
LHS,
RHS);
6622 Result->takeName(&OrigI);
6626 Inst->setHasNoSignedWrap();
6628 Inst->setHasNoUnsignedWrap();
6651 const APInt *OtherVal,
6661 assert(MulInstr->getOpcode() == Instruction::Mul);
6665 assert(
LHS->getOpcode() == Instruction::ZExt);
6666 assert(
RHS->getOpcode() == Instruction::ZExt);
6670 Type *TyA =
A->getType(), *TyB =
B->getType();
6672 WidthB = TyB->getPrimitiveSizeInBits();
6675 if (WidthB > WidthA) {
6692 unsigned TruncWidth = TI->getType()->getPrimitiveSizeInBits();
6693 if (TruncWidth > MulWidth)
6697 if (BO->getOpcode() != Instruction::And)
6700 const APInt &CVal = CI->getValue();
6716 switch (
I.getPredicate()) {
6723 if (MaxVal.
eq(*OtherVal))
6733 if (MaxVal.
eq(*OtherVal))
6747 if (WidthA < MulWidth)
6748 MulA = Builder.CreateZExt(
A, MulType);
6749 if (WidthB < MulWidth)
6750 MulB = Builder.CreateZExt(
B, MulType);
6752 Builder.CreateIntrinsic(Intrinsic::umul_with_overflow, MulType,
6753 {MulA, MulB},
nullptr,
"umul");
6760 Value *
Mul = Builder.CreateExtractValue(
Call, 0,
"umul.value");
6765 if (TI->getType()->getPrimitiveSizeInBits() == MulWidth)
6770 assert(BO->getOpcode() == Instruction::And);
6774 Value *ShortAnd = Builder.CreateAnd(
Mul, ShortMask);
6775 Value *Zext = Builder.CreateZExt(ShortAnd, BO->
getType());
6787 Value *Res = Builder.CreateExtractValue(
Call, 1);
6808 switch (
I.getPredicate()) {
6839 assert(DI && UI &&
"Instruction not defined\n");
6851 if (Usr != UI && !
DT.dominates(DB, Usr->getParent()))
6863 if (!BI || BI->getNumSuccessors() != 2)
6866 if (!IC || (IC->getOperand(0) !=
SI && IC->getOperand(1) !=
SI))
6913 const unsigned SIOpd) {
6914 assert((SIOpd == 1 || SIOpd == 2) &&
"Invalid select operand!");
6916 BasicBlock *Succ =
SI->getParent()->getTerminator()->getSuccessor(1);
6930 SI->replaceUsesOutsideBlock(
SI->getOperand(SIOpd),
SI->getParent());
6940 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6945 unsigned BitWidth = Ty->isIntOrIntVectorTy()
6946 ? Ty->getScalarSizeInBits()
6947 :
DL.getPointerTypeSizeInBits(Ty->getScalarType());
7000 if (!Cmp.hasOneUse())
7009 if (!isMinMaxCmp(
I)) {
7014 if (Op1Min == Op0Max)
7019 if (*CmpC == Op0Min + 1)
7021 ConstantInt::get(Op1->getType(), *CmpC - 1));
7031 if (Op1Max == Op0Min)
7036 if (*CmpC == Op0Max - 1)
7038 ConstantInt::get(Op1->getType(), *CmpC + 1));
7048 if (Op1Min == Op0Max)
7052 if (*CmpC == Op0Min + 1)
7054 ConstantInt::get(Op1->getType(), *CmpC - 1));
7059 if (Op1Max == Op0Min)
7063 if (*CmpC == Op0Max - 1)
7065 ConstantInt::get(Op1->getType(), *CmpC + 1));
7082 APInt Op0KnownZeroInverted = ~Op0Known.Zero;
7085 Value *LHS =
nullptr;
7088 *LHSC != Op0KnownZeroInverted)
7094 Type *XTy =
X->getType();
7096 APInt C2 = Op0KnownZeroInverted;
7097 APInt C2Pow2 = (C2 & ~(*C1 - 1)) + *C1;
7103 auto *CmpC = ConstantInt::get(XTy, Log2C2 - Log2C1);
7113 (Op0Known & Op1Known) == Op0Known)
7119 if (Op1Min == Op0Max)
7123 if (Op1Max == Op0Min)
7127 if (Op1Min == Op0Max)
7131 if (Op1Max == Op0Min)
7139 if ((
I.isSigned() || (
I.isUnsigned() && !
I.hasSameSign())) &&
7142 I.setPredicate(
I.getUnsignedPredicate());
7160 return BinaryOperator::CreateAnd(
Builder.CreateIsNull(
X),
Y);
7166 return BinaryOperator::CreateOr(
Builder.CreateIsNull(
X),
Y);
7177 bool IsSExt = ExtI->
getOpcode() == Instruction::SExt;
7179 auto CreateRangeCheck = [&] {
7194 }
else if (!IsSExt || HasOneUse) {
7199 return CreateRangeCheck();
7201 }
else if (IsSExt ?
C->isAllOnes() :
C->isOne()) {
7209 }
else if (!IsSExt || HasOneUse) {
7214 return CreateRangeCheck();
7228 Instruction::ICmp, Pred1,
X,
7247 Value *Op0 =
I.getOperand(0);
7248 Value *Op1 =
I.getOperand(1);
7254 if (!FlippedStrictness)
7257 return new ICmpInst(FlippedStrictness->first, Op0, FlippedStrictness->second);
7275 I.setName(
I.getName() +
".not");
7286 Value *
A =
I.getOperand(0), *
B =
I.getOperand(1);
7287 assert(
A->getType()->isIntOrIntVectorTy(1) &&
"Bools only");
7293 switch (
I.getPredicate()) {
7302 switch (
I.getPredicate()) {
7312 switch (
I.getPredicate()) {
7321 return BinaryOperator::CreateXor(
A,
B);
7329 return BinaryOperator::CreateAnd(Builder.CreateNot(
A),
B);
7337 return BinaryOperator::CreateAnd(Builder.CreateNot(
B),
A);
7345 return BinaryOperator::CreateOr(Builder.CreateNot(
A),
B);
7353 return BinaryOperator::CreateOr(Builder.CreateNot(
B),
A);
7401 Value *NewX = Builder.CreateLShr(
X,
Y,
X->getName() +
".highbits");
7409 Value *
LHS = Cmp.getOperand(0), *
RHS = Cmp.getOperand(1);
7413 Value *V = Builder.CreateCmp(Pred,
X,
Y, Cmp.getName());
7415 I->copyIRFlags(&Cmp);
7416 Module *M = Cmp.getModule();
7418 M, Intrinsic::vector_reverse, V->getType());
7425 (
LHS->hasOneUse() ||
RHS->hasOneUse()))
7426 return createCmpReverse(Pred, V1, V2);
7430 return createCmpReverse(Pred, V1,
RHS);
7434 return createCmpReverse(Pred,
LHS, V2);
7445 V1Ty == V2->
getType() && (
LHS->hasOneUse() ||
RHS->hasOneUse())) {
7446 Value *NewCmp = Builder.CreateCmp(Pred, V1, V2);
7459 Constant *ScalarC =
C->getSplatValue(
true);
7467 Value *NewCmp = Builder.CreateCmp(Pred, V1,
C);
7478 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7484 if (
match(Op0, UAddOvResultPat) &&
7495 (Op0 ==
A || Op0 ==
B))
7505 if (!
I.getOperand(0)->getType()->isPointerTy() ||
7507 I.getParent()->getParent(),
7508 I.getOperand(0)->getType()->getPointerAddressSpace())) {
7514 Op->isLaunderOrStripInvariantGroup()) {
7516 Op->getOperand(0),
I.getOperand(1));
7528 Value *Const =
I.getOperand(1);
7546 Type *VecEltTy = VecTy->getElementType();
7548 DL.getTypeSizeInBits(VecEltTy) * VecTy->getNumElements();
7549 if (!
DL.fitsInLegalInteger(ScalarBW))
7553 ? ConstantInt::get(ScalarTy, 0)
7556 Builder.CreateBitCast(Vec, ScalarTy), NewConst);
7568 if (
I.getType()->isVectorTy())
7591 if (!LHSTy || !LHSTy->getElementType()->isIntegerTy())
7594 LHSTy->getNumElements() * LHSTy->getElementType()->getIntegerBitWidth();
7596 if (!
DL.isLegalInteger(NumBits))
7600 auto *ScalarTy = Builder.getIntNTy(NumBits);
7601 LHS = Builder.CreateBitCast(
LHS, ScalarTy,
LHS->getName() +
".scalar");
7602 RHS = Builder.CreateBitCast(
RHS, ScalarTy,
RHS->getName() +
".scalar");
7658 bool IsIntMinPosion =
C->isAllOnesValue();
7670 CxtI, IsIntMinPosion
7671 ?
Builder.CreateICmpSGT(
X, AllOnesValue)
7673 X, ConstantInt::get(
X->getType(),
SMin + 1)));
7679 CxtI, IsIntMinPosion
7680 ?
Builder.CreateICmpSLT(
X, NullValue)
7682 X, ConstantInt::get(
X->getType(),
SMin)));
7695 auto CheckUGT1 = [](
const APInt &Divisor) {
return Divisor.ugt(1); };
7710 auto CheckNE0 = [](
const APInt &Shift) {
return !Shift.isZero(); };
7730 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7737 if (Op0Cplxity < Op1Cplxity) {
7752 if (
Value *V = dyn_castNegVal(SelectTrue)) {
7753 if (V == SelectFalse)
7755 }
else if (
Value *V = dyn_castNegVal(SelectFalse)) {
7756 if (V == SelectTrue)
7865 if (
I.isCommutative()) {
7866 if (
auto Pair = matchSymmetricPair(
I.getOperand(0),
I.getOperand(1))) {
7890 (Op0->
hasOneUse() || Op1->hasOneUse())) {
7895 Cond, Res, NewICMP,
"",
nullptr,
7902 Cond, NewICMP, Res,
"",
nullptr,
7918 bool I0NUW = I0->hasNoUnsignedWrap();
7919 bool I1NUW = I1->hasNoUnsignedWrap();
7920 bool I0NSW = I0->hasNoSignedWrap();
7921 bool I1NSW = I1->hasNoSignedWrap();
7925 ((I0NUW || I0NSW) && (I1NUW || I1NSW)))) {
7927 ConstantInt::get(Op0->
getType(), 0));
7934 assert(Op1->getType()->isPointerTy() &&
7935 "Comparing pointer with non-pointer?");
7964 bool ConsumesOp0, ConsumesOp1;
7967 (ConsumesOp0 || ConsumesOp1)) {
7970 assert(InvOp0 && InvOp1 &&
7971 "Mismatch between isFreeToInvert and getFreelyInverted");
7972 return new ICmpInst(
I.getSwappedPredicate(), InvOp0, InvOp1);
7984 if (AddI->
getOpcode() == Instruction::Add &&
7985 OptimizeOverflowCheck(Instruction::Add,
false,
X,
Y, *AddI,
7986 Result, Overflow)) {
8004 if ((
I.isUnsigned() ||
I.isEquality()) &&
8007 Y->getType()->getScalarSizeInBits() == 1 &&
8008 (Op0->
hasOneUse() || Op1->hasOneUse())) {
8015 unsigned ShiftOpc = ShiftI->
getOpcode();
8016 if ((ExtOpc == Instruction::ZExt && ShiftOpc == Instruction::LShr) ||
8017 (ExtOpc == Instruction::SExt && ShiftOpc == Instruction::AShr)) {
8051 if (EVI->getIndices()[0] == 0 && ACXI->getCompareOperand() == Op1 &&
8058 if (
I.getType()->isVectorTy())
8070 const APInt *C1, *C2;
8077 Type *InputTy =
A->getType();
8084 TruncC1.
setBit(InputBitWidth - 1);
8088 ConstantInt::get(InputTy, C2->
trunc(InputBitWidth)));
8108 if (MantissaWidth == -1)
8115 if (
I.isEquality()) {
8117 bool IsExact =
false;
8118 APSInt RHSCvt(IntWidth, LHSUnsigned);
8127 if (*RHS != RHSRoundInt) {
8147 if ((
int)IntWidth > MantissaWidth) {
8149 int Exp =
ilogb(*RHS);
8152 if (MaxExponent < (
int)IntWidth - !LHSUnsigned)
8158 if (MantissaWidth <= Exp && Exp <= (
int)IntWidth - !LHSUnsigned)
8167 assert(!RHS->isNaN() &&
"NaN comparison not already folded!");
8170 switch (
I.getPredicate()) {
8261 APSInt RHSInt(IntWidth, LHSUnsigned);
8264 if (!RHS->isZero()) {
8279 if (RHS->isNegative())
8285 if (RHS->isNegative())
8291 if (RHS->isNegative())
8298 if (!RHS->isNegative())
8304 if (RHS->isNegative())
8310 if (RHS->isNegative())
8316 if (RHS->isNegative())
8323 if (!RHS->isNegative())
8377 if (
C->isNegative())
8378 Pred =
I.getSwappedPredicate();
8394 bool RoundDown =
false;
8419 auto NextValue = [](
const APFloat &
Value,
bool RoundDown) {
8421 NextValue.
next(RoundDown);
8425 APFloat NextCValue = NextValue(*CValue, RoundDown);
8431 APFloat ExtCValue = ConvertFltSema(*CValue, DestFltSema);
8432 APFloat ExtNextCValue = ConvertFltSema(NextCValue, DestFltSema);
8439 APFloat PrevCValue = NextValue(*CValue, !RoundDown);
8440 APFloat Bias = ConvertFltSema(*CValue - PrevCValue, DestFltSema);
8442 ExtNextCValue = ExtCValue + Bias;
8449 C.getType()->getScalarType()->getFltSemantics();
8452 APFloat MidValue = ConvertFltSema(ExtMidValue, SrcFltSema);
8453 if (MidValue != *CValue)
8454 ExtMidValue.
next(!RoundDown);
8462 if (ConvertFltSema(ExtMidValue, SrcFltSema).isInfinity())
8466 APFloat NextExtMidValue = NextValue(ExtMidValue, RoundDown);
8467 if (ConvertFltSema(NextExtMidValue, SrcFltSema).
isFinite())
8472 ConstantFP::get(DestType, ExtMidValue),
"", &
I);
8485 if (!
C->isPosZero()) {
8486 if (!
C->isSmallestNormalized())
8499 switch (
I.getPredicate()) {
8525 switch (
I.getPredicate()) {
8550 assert(!
I.hasNoNaNs() &&
"fcmp should have simplified");
8555 assert(!
I.hasNoNaNs() &&
"fcmp should have simplified");
8569 return replacePredAndOp0(&
I,
I.getPredicate(),
X);
8592 I.setHasNoInfs(
false);
8594 switch (
I.getPredicate()) {
8639 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
8644 Pred =
I.getSwappedPredicate();
8653 return new FCmpInst(Pred, Op0, Zero,
"", &
I);
8689 I.getFunction()->getDenormalMode(
8696 I.setHasNoNaNs(
true);
8708 Type *OpType =
LHS->getType();
8714 if (!FloorX && !CeilX) {
8718 Pred =
I.getSwappedPredicate();
8786 if (!
I || !(
I->getOpcode() == Instruction::SIToFP ||
8787 I->getOpcode() == Instruction::UIToFP))
8790 bool IsUnsigned =
I->getOpcode() == Instruction::UIToFP;
8791 unsigned BitWidth =
I->getOperand(0)->getType()->getScalarSizeInBits();
8814 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
8816 SQ.getWithInstruction(&
I)))
8821 assert(OpType == Op1->getType() &&
"fcmp with different-typed operands?");
8846 if (
I.isCommutative()) {
8847 if (
auto Pair = matchSymmetricPair(
I.getOperand(0),
I.getOperand(1))) {
8869 return new FCmpInst(
I.getSwappedPredicate(),
X,
Y,
"", &
I);
8885 bool IsRedundantMinMaxClamp =
8947 !
F.getDenormalMode(Op1->getType()->getScalarType()->getFltSemantics())
8948 .inputsMayBeZero()) {
8956 Type *IntTy =
X->getType();
8957 const APInt &SignMask =
~APInt::getSignMask(IntTy->getScalarSizeInBits());
8958 Value *MaskX =
Builder.CreateAnd(
X, ConstantInt::get(IntTy, SignMask));
8968 case Instruction::Select:
8976 case Instruction::FSub:
8981 case Instruction::PHI:
8985 case Instruction::SIToFP:
8986 case Instruction::UIToFP:
8990 case Instruction::FDiv:
8994 case Instruction::Load:
9000 case Instruction::FPTrunc:
9021 return new FCmpInst(
I.getSwappedPredicate(),
X, NegC,
"", &
I);
9040 X->getType()->getScalarType()->getFltSemantics();
9076 Constant *NewC = ConstantFP::get(
X->getType(), TruncC);
9089 Type *IntType =
Builder.getIntNTy(
X->getType()->getScalarSizeInBits());
9102 Value *CanonLHS =
nullptr;
9105 if (CanonLHS == Op1)
9106 return new FCmpInst(Pred, Op1, Op1,
"", &
I);
9108 Value *CanonRHS =
nullptr;
9111 if (CanonRHS == Op0)
9112 return new FCmpInst(Pred, Op0, Op0,
"", &
I);
9115 if (CanonLHS && CanonRHS)
9116 return new FCmpInst(Pred, CanonLHS, CanonRHS,
"", &
I);
9119 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< 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 matchBooleanMap(Value *V, Value *&Cond, Constant *&TrueC, Constant *&FalseC)
Try to match V as a boolean-controlled value: either select i1 Cond, C_true, C_false zext i1 Cond (eq...
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 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 TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static SymbolRef::Type getType(const Symbol *Sym)
static constexpr roundingMode rmTowardZero
static constexpr roundingMode rmNearestTiesToEven
opStatus
IEEE-754R 7: Default exception handling.
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
static APFloat getSmallestNormalized(const fltSemantics &Sem, bool Negative=false)
Returns the smallest (by magnitude) normalized finite number in the given semantics.
APInt bitcastToAPInt() const
static APFloat getLargest(const fltSemantics &Sem, bool Negative=false)
Returns the largest finite number in the given semantics.
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
ArrayRef - 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 if the block is well formed or null if the block is not well forme...
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.
Conditional or Unconditional Branch instruction.
Value * getArgOperand(unsigned i) const
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
This class is the base class for the comparison instructions.
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate getStrictPredicate() const
For example, SGE -> SGT, SLE -> SLT, ULE -> ULT, UGE -> UGT.
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.
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 Constant * getZero(Type *Ty, bool Negative=false)
This is the shared class of boolean and integer constants.
uint64_t getLimitedValue(uint64_t Limit=~0ULL) const
getLimitedValue - If the value is smaller than the specified limit, return it, otherwise return the l...
static 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...
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
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.
LLVM_ABI bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
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 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.
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 * 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
IRBuilder< TargetFolder, IRBuilderCallbackInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
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.
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
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.
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.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
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)
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
cst_pred_ty< is_lowbit_mask > m_LowBitMask()
Match an integer or vector with only the low bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
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)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
cst_pred_ty< is_sign_mask > m_SignMask()
Match an integer or vector with only the sign bit(s) set.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power-of-2.
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
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)
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.
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)
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.
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
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_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)
Combine two pattern matchers matching L && R.
MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > m_SMin(const LHS &L, const RHS &R)
m_Intrinsic_Ty< Opnd0 >::Ty m_Sqrt(const Opnd0 &Op0)
BinaryOp_match< LHS, RHS, Instruction::Xor, true > m_c_Xor(const LHS &L, const RHS &R)
Matches an Xor with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::FAdd > m_FAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
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)
MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty > m_UMax(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.
cst_pred_ty< is_lowbit_mask_or_zero > m_LowBitMaskOrZero()
Match an integer or vector with only the low bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
match_combine_or< BinaryOp_match< LHS, RHS, Instruction::Add >, DisjointOr_match< LHS, RHS > > m_AddLike(const LHS &L, const RHS &R)
Match either "add" or "or disjoint".
CastInst_match< OpTy, UIToFPInst > m_UIToFP(const OpTy &Op)
CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)
MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty > m_SMax(const LHS &L, const RHS &R)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
Signum_match< Val_t > m_Signum(const Val_t &V)
Matches a signum pattern.
CastInst_match< OpTy, SIToFPInst > m_SIToFP(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > > m_ZExtOrSExt(const OpTy &Op)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
cstfp_pred_ty< is_pos_zero_fp > m_PosZeroFP()
Match a floating-point positive zero.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
UAddWithOverflow_match< LHS_t, RHS_t, Sum_t > m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S)
Match an icmp instruction checking for unsigned overflow on addition.
m_Intrinsic_Ty< Opnd0 >::Ty m_VecReverse(const Opnd0 &Op0)
BinOpPred_match< LHS, RHS, is_irem_op > m_IRem(const LHS &L, const RHS &R)
Matches integer remainder operations.
match_combine_or< match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty >, MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > >, match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty >, MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > > > m_MaxOrMin(const LHS &L, const RHS &R)
CastInst_match< OpTy, FPTruncInst > m_FPTrunc(const OpTy &Op)
auto m_Undef()
Match an arbitrary undef constant.
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
ElementWiseBitCast_match< OpTy > m_ElementWiseBitCast(const OpTy &Op)
m_Intrinsic_Ty< Opnd0 >::Ty m_FAbs(const Opnd0 &Op0)
BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
CastOperator_match< OpTy, Instruction::PtrToInt > m_PtrToInt(const OpTy &Op)
Matches PtrToInt.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
match_unless< Ty > m_Unless(const Ty &M)
Match if the inner matcher does NOT match.
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
cst_pred_ty< icmp_pred_with_threshold > m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold)
Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.
This is an optimization pass for GlobalISel generic memory operations.
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
@ NeverOverflows
Never overflows.
@ AlwaysOverflowsHigh
Always overflows in the direction of signed/unsigned max value.
@ AlwaysOverflowsLow
Always overflows in the direction of signed/unsigned min value.
@ MayOverflow
May or may not overflow.
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.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
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 ConstantRange computeConstantRange(const Value *V, bool ForSigned, bool UseInstrInfo=true, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Determine the possible constant range of an integer or vector of integer value.
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...
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.
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.
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.
unsigned getBitWidth() const
Get the bit width of this value.
bool isConstant() const
Returns true if we know the value of all bits.
unsigned countMinLeadingZeros() const
Returns the minimum number of leading zero bits.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
APInt getMinValue() const
Return the minimal unsigned value possible given these KnownBits.
bool isStrictlyPositive() const
Returns true if this value is known to be positive.
bool isNegative() const
Returns true if this value is known to be negative.
unsigned countMinPopulation() const
Returns the number of bits known to be one.
APInt getSignedMinValue() const
Return the minimal signed value possible given these KnownBits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
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.