34using namespace PatternMatch;
36#define DEBUG_TYPE "instcombine"
45 const APInt &In2,
bool IsSigned =
false) {
48 Result = In1.
sadd_ov(In2, Overflow);
50 Result = In1.
uadd_ov(In2, Overflow);
58 const APInt &In2,
bool IsSigned =
false) {
61 Result = In1.
ssub_ov(In2, Overflow);
63 Result = In1.
usub_ov(In2, Overflow);
71 for (
auto *U :
I.users())
72 if (isa<BranchInst>(U))
82 if (!ICmpInst::isSigned(Pred))
89 if (Pred == ICmpInst::ICMP_SLT) {
90 Pred = ICmpInst::ICMP_SLE;
93 }
else if (
C.isAllOnes()) {
94 if (Pred == ICmpInst::ICMP_SGT) {
95 Pred = ICmpInst::ICMP_SGE;
114 if (
LI->isVolatile() ||
LI->getType() !=
GEP->getResultElementType() ||
120 if (!isa<ConstantArray>(
Init) && !isa<ConstantDataArray>(
Init))
123 uint64_t ArrayElementCount =
Init->getType()->getArrayNumElements();
132 if (
GEP->getNumOperands() < 3 || !isa<ConstantInt>(
GEP->getOperand(1)) ||
133 !cast<ConstantInt>(
GEP->getOperand(1))->isZero() ||
134 isa<Constant>(
GEP->getOperand(2)))
142 Type *EltTy =
Init->getType()->getArrayElementType();
143 for (
unsigned i = 3, e =
GEP->getNumOperands(); i != e; ++i) {
149 if ((
unsigned)IdxVal != IdxVal)
152 if (
StructType *STy = dyn_cast<StructType>(EltTy))
153 EltTy = STy->getElementType(IdxVal);
154 else if (
ArrayType *ATy = dyn_cast<ArrayType>(EltTy)) {
155 if (IdxVal >= ATy->getNumElements())
157 EltTy = ATy->getElementType();
165 enum { Overdefined = -3, Undefined = -2 };
174 int FirstTrueElement = Undefined, SecondTrueElement = Undefined;
178 int FirstFalseElement = Undefined, SecondFalseElement = Undefined;
186 int TrueRangeEnd = Undefined, FalseRangeEnd = Undefined;
195 for (
unsigned i = 0, e = ArrayElementCount; i != e; ++i) {
201 if (!LaterIndices.
empty()) {
216 CompareRHS,
DL, &
TLI);
218 if (isa<UndefValue>(
C)) {
221 if (TrueRangeEnd == (
int)i - 1)
223 if (FalseRangeEnd == (
int)i - 1)
230 if (!isa<ConstantInt>(
C))
235 bool IsTrueForElt = !cast<ConstantInt>(
C)->isZero();
240 if (FirstTrueElement == Undefined)
241 FirstTrueElement = TrueRangeEnd = i;
244 if (SecondTrueElement == Undefined)
245 SecondTrueElement = i;
247 SecondTrueElement = Overdefined;
250 if (TrueRangeEnd == (
int)i - 1)
253 TrueRangeEnd = Overdefined;
257 if (FirstFalseElement == Undefined)
258 FirstFalseElement = FalseRangeEnd = i;
261 if (SecondFalseElement == Undefined)
262 SecondFalseElement = i;
264 SecondFalseElement = Overdefined;
267 if (FalseRangeEnd == (
int)i - 1)
270 FalseRangeEnd = Overdefined;
275 if (i < 64 && IsTrueForElt)
276 MagicBitvector |= 1ULL << i;
281 if ((i & 8) == 0 && i >= 64 && SecondTrueElement == Overdefined &&
282 SecondFalseElement == Overdefined && TrueRangeEnd == Overdefined &&
283 FalseRangeEnd == Overdefined)
294 if (!
GEP->isInBounds()) {
297 if (
Idx->getType()->getPrimitiveSizeInBits().getFixedValue() > OffsetSize)
308 unsigned ElementSize =
312 Value *Mask = ConstantInt::get(
Idx->getType(), -1);
321 if (SecondTrueElement != Overdefined) {
324 if (FirstTrueElement == Undefined)
327 Value *FirstTrueIdx = ConstantInt::get(
Idx->getType(), FirstTrueElement);
330 if (SecondTrueElement == Undefined)
335 Value *SecondTrueIdx = ConstantInt::get(
Idx->getType(), SecondTrueElement);
337 return BinaryOperator::CreateOr(C1, C2);
342 if (SecondFalseElement != Overdefined) {
345 if (FirstFalseElement == Undefined)
348 Value *FirstFalseIdx = ConstantInt::get(
Idx->getType(), FirstFalseElement);
351 if (SecondFalseElement == Undefined)
356 Value *SecondFalseIdx =
357 ConstantInt::get(
Idx->getType(), SecondFalseElement);
359 return BinaryOperator::CreateAnd(C1, C2);
364 if (TrueRangeEnd != Overdefined) {
365 assert(TrueRangeEnd != FirstTrueElement &&
"Should emit single compare");
369 if (FirstTrueElement) {
370 Value *Offs = ConstantInt::get(
Idx->getType(), -FirstTrueElement);
375 ConstantInt::get(
Idx->getType(), TrueRangeEnd - FirstTrueElement + 1);
380 if (FalseRangeEnd != Overdefined) {
381 assert(FalseRangeEnd != FirstFalseElement &&
"Should emit single compare");
384 if (FirstFalseElement) {
385 Value *Offs = ConstantInt::get(
Idx->getType(), -FirstFalseElement);
390 ConstantInt::get(
Idx->getType(), FalseRangeEnd - FirstFalseElement);
403 if (ArrayElementCount <= Idx->
getType()->getIntegerBitWidth())
437 while (!WorkList.
empty()) {
440 while (!WorkList.
empty()) {
441 if (Explored.
size() >= 100)
451 if (!isa<GetElementPtrInst>(V) && !isa<PHINode>(V))
456 if (
auto *
GEP = dyn_cast<GEPOperator>(V)) {
458 auto IsNonConst = [](
Value *V) {
return !isa<ConstantInt>(V); };
459 if (!
GEP->isInBounds() ||
count_if(
GEP->indices(), IsNonConst) > 1)
466 if (WorkList.
back() == V) {
472 if (
auto *PN = dyn_cast<PHINode>(V)) {
474 if (isa<CatchSwitchInst>(PN->getParent()->getTerminator()))
482 for (
auto *PN : PHIs)
483 for (
Value *
Op : PN->incoming_values())
491 for (
Value *Val : Explored) {
494 auto *
PHI = dyn_cast<PHINode>(
Use);
495 auto *Inst = dyn_cast<Instruction>(Val);
497 if (Inst ==
Base || Inst ==
PHI || !Inst || !
PHI ||
501 if (
PHI->getParent() == Inst->getParent())
512 if (
auto *
PHI = dyn_cast<PHINode>(V)) {
517 if (
auto *
I = dyn_cast<Instruction>(V)) {
519 I = &*std::next(
I->getIterator());
523 if (
auto *
A = dyn_cast<Argument>(V)) {
525 BasicBlock &Entry =
A->getParent()->getEntryBlock();
531 assert(isa<Constant>(V) &&
"Setting insertion point for unknown value!");
548 Base->getContext(),
DL.getIndexTypeSizeInBits(Start->getType()));
554 for (
Value *Val : Explored) {
559 if (
auto *
PHI = dyn_cast<PHINode>(Val))
562 PHI->getName() +
".idx",
PHI->getIterator());
567 for (
Value *Val : Explored) {
571 if (
auto *
GEP = dyn_cast<GEPOperator>(Val)) {
575 if (isa<ConstantInt>(
Op) && cast<ConstantInt>(
Op)->
isZero())
576 NewInsts[
GEP] = OffsetV;
579 Op, OffsetV,
GEP->getOperand(0)->getName() +
".add");
582 if (isa<PHINode>(Val))
589 for (
Value *Val : Explored) {
594 if (
auto *
PHI = dyn_cast<PHINode>(Val)) {
596 for (
unsigned I = 0, E =
PHI->getNumIncomingValues();
I < E; ++
I) {
597 Value *NewIncoming =
PHI->getIncomingValue(
I);
600 NewIncoming = NewInsts[NewIncoming];
607 for (
Value *Val : Explored) {
614 Builder.
getInt8Ty(),
Base, NewInsts[Val], Val->getName() +
".ptr");
621 return NewInsts[Start];
684 if (!isa<GetElementPtrInst>(
RHS))
696 isa<Constant>(
RHS) && cast<Constant>(
RHS)->isNullValue() &&
718 auto EC = cast<VectorType>(GEPLHS->
getType())->getElementCount();
723 cast<Constant>(
RHS),
Base->getType()));
727 if (PtrBase != GEPRHS->getOperand(0)) {
728 bool IndicesTheSame =
731 GEPRHS->getPointerOperand()->getType() &&
735 if (GEPLHS->
getOperand(i) != GEPRHS->getOperand(i)) {
736 IndicesTheSame =
false;
749 if (GEPLHS->
isInBounds() && GEPRHS->isInBounds() &&
751 (GEPRHS->hasAllConstantIndices() || GEPRHS->hasOneUse()) &&
755 Value *LOffset = EmitGEPOffset(GEPLHS);
756 Value *ROffset = EmitGEPOffset(GEPRHS);
763 if (LHSIndexTy != RHSIndexTy) {
782 bool GEPsInBounds = GEPLHS->
isInBounds() && GEPRHS->isInBounds();
786 unsigned NumDifferences = 0;
787 unsigned DiffOperand = 0;
788 for (
unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i)
789 if (GEPLHS->
getOperand(i) != GEPRHS->getOperand(i)) {
791 Type *RHSType = GEPRHS->getOperand(i)->getType();
802 if (NumDifferences++)
break;
806 if (NumDifferences == 0)
810 else if (NumDifferences == 1 && GEPsInBounds) {
812 Value *RHSV = GEPRHS->getOperand(DiffOperand);
820 Value *L = EmitGEPOffset(GEPLHS,
true);
821 Value *R = EmitGEPOffset(GEPRHS,
true);
848 bool Captured =
false;
853 CmpCaptureTracker(
AllocaInst *Alloca) : Alloca(Alloca) {}
855 void tooManyUses()
override { Captured =
true; }
857 bool captured(
const Use *U)
override {
858 auto *ICmp = dyn_cast<ICmpInst>(U->getUser());
866 auto Res = ICmps.
insert({ICmp, 0});
867 Res.first->second |= 1u << U->getOperandNo();
876 CmpCaptureTracker Tracker(Alloca);
878 if (Tracker.Captured)
881 bool Changed =
false;
882 for (
auto [ICmp,
Operands] : Tracker.ICmps) {
888 auto *Res = ConstantInt::get(
914 assert(!!
C &&
"C should not be zero!");
920 Constant *R = ConstantInt::get(
X->getType(),
930 ConstantInt::get(
X->getType(), -
C));
942 ConstantInt::get(
X->getType(),
SMax -
C));
953 ConstantInt::get(
X->getType(),
SMax - (
C - 1)));
962 assert(
I.isEquality() &&
"Cannot fold icmp gt/lt");
965 if (
I.getPredicate() ==
I.ICMP_NE)
974 bool IsAShr = isa<AShrOperator>(
I.getOperand(0));
986 return getICmp(
I.ICMP_UGT,
A,
987 ConstantInt::get(
A->getType(), AP2.
logBase2()));
999 if (IsAShr && AP1 == AP2.
ashr(Shift)) {
1003 return getICmp(
I.ICMP_UGE,
A, ConstantInt::get(
A->getType(), Shift));
1004 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1005 }
else if (AP1 == AP2.
lshr(Shift)) {
1006 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1012 auto *TorF = ConstantInt::get(
I.getType(),
I.getPredicate() ==
I.ICMP_NE);
1021 assert(
I.isEquality() &&
"Cannot fold icmp gt/lt");
1024 if (
I.getPredicate() ==
I.ICMP_NE)
1035 if (!AP1 && AP2TrailingZeros != 0)
1038 ConstantInt::get(
A->getType(), AP2.
getBitWidth() - AP2TrailingZeros));
1046 if (Shift > 0 && AP2.
shl(Shift) == AP1)
1047 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1051 auto *TorF = ConstantInt::get(
I.getType(),
I.getPredicate() ==
I.ICMP_NE);
1072 Instruction *AddWithCst = cast<Instruction>(
I.getOperand(0));
1080 if (NewWidth != 7 && NewWidth != 15 && NewWidth != 31)
1104 if (U == AddWithCst)
1122 I.getModule(), Intrinsic::sadd_with_overflow, NewType);
1151 if (!
I.isEquality())
1182 APInt(XBitWidth, XBitWidth - 1))))
1184 }
else if (isa<BinaryOperator>(Val) &&
1209 return new ICmpInst(Pred,
B, Cmp.getOperand(1));
1211 return new ICmpInst(Pred,
A, Cmp.getOperand(1));
1228 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1240 return new ICmpInst(Pred,
Y, Cmp.getOperand(1));
1246 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1248 auto *BO0 = cast<OverflowingBinaryOperator>(Cmp.getOperand(0));
1249 if (BO0->hasNoUnsignedWrap() || BO0->hasNoSignedWrap()) {
1257 return new ICmpInst(Pred,
Y, Cmp.getOperand(1));
1262 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1294 Value *Op0 = Cmp.getOperand(0), *Op1 = Cmp.getOperand(1);
1307 if (
auto *Phi = dyn_cast<PHINode>(Op0))
1308 if (
all_of(Phi->operands(), [](
Value *V) { return isa<Constant>(V); })) {
1310 for (
Value *V : Phi->incoming_values()) {
1319 for (
auto [V, Pred] :
zip(Ops, Phi->blocks()))
1334 Value *
X = Cmp.getOperand(0), *
Y = Cmp.getOperand(1);
1367 if (Cmp.isEquality() || (IsSignBit &&
hasBranchUse(Cmp)))
1372 if (Cmp.hasOneUse() &&
1386 if (!
match(BI->getCondition(),
1392 if (
auto *V = handleDomCond(DomPred, DomC))
1412 if (
C.isOne() &&
C.getBitWidth() > 1) {
1417 ConstantInt::get(V->getType(), 1));
1420 Type *SrcTy =
X->getType();
1431 auto NewPred = (Pred == Cmp.ICMP_EQ) ? Cmp.ICMP_UGE : Cmp.ICMP_ULT;
1432 return new ICmpInst(NewPred,
Y, ConstantInt::get(SrcTy, DstBits));
1437 return new ICmpInst(Pred,
Y, ConstantInt::get(SrcTy,
C.logBase2()));
1440 if (Cmp.isEquality() && Trunc->
hasOneUse()) {
1443 if (!SrcTy->
isVectorTy() && shouldChangeType(DstBits, SrcBits)) {
1447 Constant *WideC = ConstantInt::get(SrcTy,
C.zext(SrcBits));
1456 if ((Known.
Zero | Known.
One).countl_one() >= SrcBits - DstBits) {
1458 APInt NewRHS =
C.zext(SrcBits);
1460 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy, NewRHS));
1468 const APInt *ShAmtC;
1489 bool YIsSExt =
false;
1492 unsigned NoWrapFlags = cast<TruncInst>(Cmp.getOperand(0))->getNoWrapKind() &
1493 cast<TruncInst>(Cmp.getOperand(1))->getNoWrapKind();
1494 if (Cmp.isSigned()) {
1505 if (
X->getType() !=
Y->getType() &&
1506 (!Cmp.getOperand(0)->hasOneUse() || !Cmp.getOperand(1)->hasOneUse()))
1508 if (!isDesirableIntType(
X->getType()->getScalarSizeInBits()) &&
1509 isDesirableIntType(
Y->getType()->getScalarSizeInBits())) {
1511 Pred = Cmp.getSwappedPredicate(Pred);
1515 else if (!Cmp.isSigned() &&
1525 isa<SExtInst>(Cmp.getOperand(0)) || isa<SExtInst>(Cmp.getOperand(1));
1529 Type *TruncTy = Cmp.getOperand(0)->getType();
1534 if (isDesirableIntType(TruncBits) &&
1535 !isDesirableIntType(
X->getType()->getScalarSizeInBits()))
1558 bool TrueIfSigned =
false;
1575 if (
Xor->hasOneUse()) {
1577 if (!Cmp.isEquality() && XorC->
isSignMask()) {
1578 Pred = Cmp.getFlippedSignednessPredicate();
1579 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(),
C ^ *XorC));
1584 Pred = Cmp.getFlippedSignednessPredicate();
1585 Pred = Cmp.getSwappedPredicate(Pred);
1586 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(),
C ^ *XorC));
1593 if (*XorC == ~
C && (
C + 1).isPowerOf2())
1596 if (*XorC ==
C && (
C + 1).isPowerOf2())
1601 if (*XorC == -
C &&
C.isPowerOf2())
1603 ConstantInt::get(
X->getType(), ~
C));
1605 if (*XorC ==
C && (-
C).isPowerOf2())
1607 ConstantInt::get(
X->getType(), ~
C));
1629 const APInt *ShiftC;
1634 Type *XType =
X->getType();
1640 return new ICmpInst(Pred,
Add, ConstantInt::get(XType, Bound));
1649 if (!Shift || !Shift->
isShift())
1657 unsigned ShiftOpcode = Shift->
getOpcode();
1658 bool IsShl = ShiftOpcode == Instruction::Shl;
1661 APInt NewAndCst, NewCmpCst;
1662 bool AnyCmpCstBitsShiftedOut;
1663 if (ShiftOpcode == Instruction::Shl) {
1671 NewCmpCst = C1.
lshr(*C3);
1672 NewAndCst = C2.
lshr(*C3);
1673 AnyCmpCstBitsShiftedOut = NewCmpCst.
shl(*C3) != C1;
1674 }
else if (ShiftOpcode == Instruction::LShr) {
1679 NewCmpCst = C1.
shl(*C3);
1680 NewAndCst = C2.
shl(*C3);
1681 AnyCmpCstBitsShiftedOut = NewCmpCst.
lshr(*C3) != C1;
1687 assert(ShiftOpcode == Instruction::AShr &&
"Unknown shift opcode");
1688 NewCmpCst = C1.
shl(*C3);
1689 NewAndCst = C2.
shl(*C3);
1690 AnyCmpCstBitsShiftedOut = NewCmpCst.
ashr(*C3) != C1;
1691 if (NewAndCst.
ashr(*C3) != C2)
1695 if (AnyCmpCstBitsShiftedOut) {
1705 Shift->
getOperand(0), ConstantInt::get(
And->getType(), NewAndCst));
1706 return new ICmpInst(Cmp.getPredicate(),
1707 NewAnd, ConstantInt::get(
And->getType(), NewCmpCst));
1738 if (isICMP_NE && Cmp.getType()->isVectorTy() && C1.
isZero() &&
1740 return new TruncInst(
And->getOperand(0), Cmp.getType());
1748 if (!
And->hasOneUse())
1751 if (Cmp.isEquality() && C1.
isZero()) {
1769 Constant *NegBOC = ConstantInt::get(
And->getType(), -NewC2);
1771 return new ICmpInst(NewPred,
X, NegBOC);
1789 if (!Cmp.getType()->isVectorTy()) {
1790 Type *WideType = W->getType();
1792 Constant *ZextC1 = ConstantInt::get(WideType, C1.
zext(WideScalarBits));
1793 Constant *ZextC2 = ConstantInt::get(WideType, C2->
zext(WideScalarBits));
1795 return new ICmpInst(Cmp.getPredicate(), NewAnd, ZextC1);
1806 if (!Cmp.isSigned() && C1.
isZero() &&
And->getOperand(0)->hasOneUse() &&
1808 Constant *One = cast<Constant>(
And->getOperand(1));
1813 unsigned UsesRemoved = 0;
1814 if (
And->hasOneUse())
1816 if (
Or->hasOneUse())
1823 if (UsesRemoved >= RequireUsesRemoved) {
1827 One,
Or->getName());
1839 if (!Cmp.getParent()->getParent()->hasFnAttribute(
1840 Attribute::NoImplicitFloat) &&
1843 Type *FPType = V->getType()->getScalarType();
1845 APInt ExponentMask =
1847 if (C1 == ExponentMask) {
1880 Constant *MinSignedC = ConstantInt::get(
1884 return new ICmpInst(NewPred,
X, MinSignedC);
1893 if (
auto *C2 = dyn_cast<ConstantInt>(
Y))
1894 if (
auto *
LI = dyn_cast<LoadInst>(
X))
1895 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(
LI->getOperand(0)))
1896 if (
auto *GV = dyn_cast<GlobalVariable>(
GEP->getOperand(0)))
1901 if (!Cmp.isEquality())
1907 if (Cmp.getOperand(1) ==
Y &&
C.isNegatedPowerOf2()) {
1910 return new ICmpInst(NewPred,
X,
SubOne(cast<Constant>(Cmp.getOperand(1))));
1923 assert(Cmp.isEquality() &&
"Not expecting non-equality predicates");
1925 const APInt *TC, *FC;
1942 X->getType()->isIntOrIntVectorTy(1) && (
C.isZero() ||
C.isOne())) {
1948 return BinaryOperator::CreateAnd(TruncY,
X);
1980 while (!WorkList.
empty()) {
1981 auto MatchOrOperatorArgument = [&](
Value *OrOperatorArgument) {
1984 if (
match(OrOperatorArgument,
1990 if (
match(OrOperatorArgument,
2000 Value *OrOperatorLhs, *OrOperatorRhs;
2002 if (!
match(CurrentValue,
2007 MatchOrOperatorArgument(OrOperatorRhs);
2008 MatchOrOperatorArgument(OrOperatorLhs);
2014 CmpValues.
rbegin()->second);
2016 for (
auto It = CmpValues.
rbegin() + 1; It != CmpValues.
rend(); ++It) {
2018 LhsCmp = Builder.
CreateBinOp(BOpc, LhsCmp, RhsCmp);
2034 ConstantInt::get(V->getType(), 1));
2037 Value *OrOp0 =
Or->getOperand(0), *OrOp1 =
Or->getOperand(1);
2042 cast<PossiblyDisjointInst>(
Or)->isDisjoint()) {
2045 return new ICmpInst(Pred, OrOp0, NewC);
2049 if (
match(OrOp1,
m_APInt(MaskC)) && Cmp.isEquality()) {
2050 if (*MaskC ==
C && (
C + 1).isPowerOf2()) {
2055 return new ICmpInst(Pred, OrOp0, OrOp1);
2062 if (
Or->hasOneUse()) {
2064 Constant *NewC = ConstantInt::get(
Or->getType(),
C ^ (*MaskC));
2076 Constant *NewC = ConstantInt::get(
X->getType(), TrueIfSigned ? 1 : 0);
2104 if (!Cmp.isEquality() || !
C.isZero() || !
Or->hasOneUse())
2136 if (Cmp.isEquality() &&
C.isZero() &&
X ==
Mul->getOperand(1) &&
2137 (
Mul->hasNoUnsignedWrap() ||
Mul->hasNoSignedWrap()))
2159 if (Cmp.isEquality()) {
2161 if (
Mul->hasNoSignedWrap() &&
C.srem(*MulC).isZero()) {
2162 Constant *NewC = ConstantInt::get(MulTy,
C.sdiv(*MulC));
2170 if (
C.urem(*MulC).isZero()) {
2173 if ((*MulC & 1).isOne() ||
Mul->hasNoUnsignedWrap()) {
2174 Constant *NewC = ConstantInt::get(MulTy,
C.udiv(*MulC));
2187 if (
C.isMinSignedValue() && MulC->
isAllOnes())
2193 NewC = ConstantInt::get(
2197 "Unexpected predicate");
2198 NewC = ConstantInt::get(
2203 NewC = ConstantInt::get(
2207 "Unexpected predicate");
2208 NewC = ConstantInt::get(
2213 return NewC ?
new ICmpInst(Pred,
X, NewC) :
nullptr;
2224 unsigned TypeBits =
C.getBitWidth();
2225 bool CIsPowerOf2 =
C.isPowerOf2();
2227 if (Cmp.isUnsigned()) {
2240 unsigned CLog2 =
C.logBase2();
2241 return new ICmpInst(Pred,
Y, ConstantInt::get(ShiftType, CLog2));
2242 }
else if (Cmp.isSigned()) {
2243 Constant *BitWidthMinusOne = ConstantInt::get(ShiftType, TypeBits - 1);
2264 const APInt *ShiftVal;
2294 const APInt *ShiftAmt;
2300 unsigned TypeBits =
C.getBitWidth();
2301 if (ShiftAmt->
uge(TypeBits))
2313 APInt ShiftedC =
C.ashr(*ShiftAmt);
2314 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2317 C.ashr(*ShiftAmt).shl(*ShiftAmt) ==
C) {
2318 APInt ShiftedC =
C.ashr(*ShiftAmt);
2319 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2326 assert(!
C.isMinSignedValue() &&
"Unexpected icmp slt");
2327 APInt ShiftedC = (
C - 1).ashr(*ShiftAmt) + 1;
2328 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2338 APInt ShiftedC =
C.lshr(*ShiftAmt);
2339 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2342 C.lshr(*ShiftAmt).shl(*ShiftAmt) ==
C) {
2343 APInt ShiftedC =
C.lshr(*ShiftAmt);
2344 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2351 assert(
C.ugt(0) &&
"ult 0 should have been eliminated");
2352 APInt ShiftedC = (
C - 1).lshr(*ShiftAmt) + 1;
2353 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2357 if (Cmp.isEquality() && Shl->
hasOneUse()) {
2363 Constant *LShrC = ConstantInt::get(ShType,
C.lshr(*ShiftAmt));
2368 bool TrueIfSigned =
false;
2380 if (Cmp.isUnsigned() && Shl->
hasOneUse()) {
2382 if ((
C + 1).isPowerOf2() &&
2390 if (
C.isPowerOf2() &&
2407 if (Shl->
hasOneUse() && Amt != 0 &&
C.countr_zero() >= Amt &&
2410 if (
auto *ShVTy = dyn_cast<VectorType>(ShType))
2413 ConstantInt::get(TruncTy,
C.ashr(*ShiftAmt).trunc(TypeBits - Amt));
2428 if (Cmp.isEquality() && Shr->
isExact() &&
C.isZero())
2429 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
2431 bool IsAShr = Shr->
getOpcode() == Instruction::AShr;
2432 const APInt *ShiftValC;
2434 if (Cmp.isEquality())
2452 assert(ShiftValC->
uge(
C) &&
"Expected simplify of compare");
2453 assert((IsUGT || !
C.isZero()) &&
"Expected X u< 0 to simplify");
2455 unsigned CmpLZ = IsUGT ?
C.countl_zero() : (
C - 1).
countl_zero();
2463 const APInt *ShiftAmtC;
2469 unsigned TypeBits =
C.getBitWidth();
2471 if (ShAmtVal >= TypeBits || ShAmtVal == 0)
2474 bool IsExact = Shr->
isExact();
2485 APInt ShiftedC =
C.shl(ShAmtVal);
2486 if (ShiftedC.
ashr(ShAmtVal) ==
C)
2487 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2491 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2492 if (!
C.isMaxSignedValue() && !(
C + 1).shl(ShAmtVal).isMinSignedValue() &&
2493 (ShiftedC + 1).ashr(ShAmtVal) == (
C + 1))
2494 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2500 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2501 if ((ShiftedC + 1).ashr(ShAmtVal) == (
C + 1) ||
2502 (
C + 1).shl(ShAmtVal).isMinSignedValue())
2503 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2510 if (
C.getBitWidth() > 2 &&
C.getNumSignBits() <= ShAmtVal) {
2520 }
else if (!IsAShr) {
2524 APInt ShiftedC =
C.shl(ShAmtVal);
2525 if (ShiftedC.
lshr(ShAmtVal) ==
C)
2526 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2530 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2531 if ((ShiftedC + 1).lshr(ShAmtVal) == (
C + 1))
2532 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2536 if (!Cmp.isEquality())
2544 assert(((IsAShr &&
C.shl(ShAmtVal).ashr(ShAmtVal) ==
C) ||
2545 (!IsAShr &&
C.shl(ShAmtVal).lshr(ShAmtVal) ==
C)) &&
2546 "Expected icmp+shr simplify did not occur.");
2551 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy,
C << ShAmtVal));
2557 ConstantInt::get(ShrTy, (
C + 1).shl(ShAmtVal)));
2560 ConstantInt::get(ShrTy, (
C + 1).shl(ShAmtVal) - 1));
2567 Constant *Mask = ConstantInt::get(ShrTy, Val);
2569 return new ICmpInst(Pred,
And, ConstantInt::get(ShrTy,
C << ShAmtVal));
2592 const APInt *DivisorC;
2601 !
C.isStrictlyPositive()))
2607 Constant *MaskC = ConstantInt::get(Ty, SignMask | (*DivisorC - 1));
2611 return new ICmpInst(Pred,
And, ConstantInt::get(Ty,
C));
2638 assert(*C2 != 0 &&
"udiv 0, X should have been simplified already.");
2643 "icmp ugt X, UINT_MAX should have been simplified already.");
2645 ConstantInt::get(Ty, C2->
udiv(
C + 1)));
2650 assert(
C != 0 &&
"icmp ult X, 0 should have been simplified already.");
2652 ConstantInt::get(Ty, C2->
udiv(
C)));
2666 bool DivIsSigned = Div->
getOpcode() == Instruction::SDiv;
2676 if (Cmp.isEquality() && Div->
hasOneUse() &&
C.isSignBitSet() &&
2677 (!DivIsSigned ||
C.isMinSignedValue())) {
2702 if (!Cmp.isEquality() && DivIsSigned != Cmp.isSigned())
2721 bool ProdOV = (DivIsSigned ? Prod.
sdiv(*C2) : Prod.
udiv(*C2)) !=
C;
2734 int LoOverflow = 0, HiOverflow = 0;
2735 APInt LoBound, HiBound;
2740 HiOverflow = LoOverflow = ProdOV;
2749 LoBound = -(RangeSize - 1);
2750 HiBound = RangeSize;
2751 }
else if (
C.isStrictlyPositive()) {
2753 HiOverflow = LoOverflow = ProdOV;
2759 LoOverflow = HiOverflow = ProdOV ? -1 : 0;
2761 APInt DivNeg = -RangeSize;
2762 LoOverflow =
addWithOverflow(LoBound, HiBound, DivNeg,
true) ? -1 : 0;
2770 LoBound = RangeSize + 1;
2771 HiBound = -RangeSize;
2772 if (HiBound == *C2) {
2776 }
else if (
C.isStrictlyPositive()) {
2779 HiOverflow = LoOverflow = ProdOV ? -1 : 0;
2785 LoOverflow = HiOverflow = ProdOV;
2798 if (LoOverflow && HiOverflow)
2802 X, ConstantInt::get(Ty, LoBound));
2805 X, ConstantInt::get(Ty, HiBound));
2809 if (LoOverflow && HiOverflow)
2813 X, ConstantInt::get(Ty, LoBound));
2816 X, ConstantInt::get(Ty, HiBound));
2821 if (LoOverflow == +1)
2823 if (LoOverflow == -1)
2825 return new ICmpInst(Pred,
X, ConstantInt::get(Ty, LoBound));
2828 if (HiOverflow == +1)
2830 if (HiOverflow == -1)
2863 ((Cmp.isUnsigned() && HasNUW) || (Cmp.isSigned() && HasNSW)) &&
2865 return new ICmpInst(SwappedPred,
Y, ConstantInt::get(Ty, SubResult));
2873 if (Cmp.isEquality() &&
C.isZero() &&
2909 (*C2 & (
C - 1)) == (
C - 1))
2922 return new ICmpInst(SwappedPred,
Add, ConstantInt::get(Ty, ~
C));
2928 auto FoldConstant = [&](
bool Val) {
2932 cast<VectorType>(Op0->
getType())->getElementCount(), Res);
2936 switch (Table.to_ulong()) {
2938 return FoldConstant(
false);
2968 return FoldConstant(
true);
2991 unsigned BW =
C.getBitWidth();
2992 std::bitset<4> Table;
2993 auto ComputeTable = [&](
bool Op0Val,
bool Op1Val) {
2996 Res += isa<ZExtInst>(Ext0) ? 1 : -1;
2998 Res += isa<ZExtInst>(Ext1) ? 1 : -1;
3002 Table[0] = ComputeTable(
false,
false);
3003 Table[1] = ComputeTable(
false,
true);
3004 Table[2] = ComputeTable(
true,
false);
3005 Table[3] = ComputeTable(
true,
true);
3020 if ((
Add->hasNoSignedWrap() &&
3022 (
Add->hasNoUnsignedWrap() &&
3026 Cmp.isSigned() ?
C.ssub_ov(*C2, Overflow) :
C.usub_ov(*C2, Overflow);
3032 return new ICmpInst(Pred,
X, ConstantInt::get(Ty, NewC));
3038 if (Cmp.isSigned()) {
3039 if (
Lower.isSignMask())
3041 if (
Upper.isSignMask())
3044 if (
Lower.isMinValue())
3046 if (
Upper.isMinValue())
3079 if (!
Add->hasOneUse())
3102 ConstantInt::get(Ty, ~
C));
3122 Value *EqualVal = SI->getTrueValue();
3123 Value *UnequalVal = SI->getFalseValue();
3146 auto FlippedStrictness =
3148 PredB, cast<Constant>(RHS2));
3149 if (!FlippedStrictness)
3152 "basic correctness failure");
3153 RHS2 = FlippedStrictness->second;
3165 assert(
C &&
"Cmp RHS should be a constant int!");
3171 Value *OrigLHS, *OrigRHS;
3172 ConstantInt *C1LessThan, *C2Equal, *C3GreaterThan;
3173 if (Cmp.hasOneUse() &&
3176 assert(C1LessThan && C2Equal && C3GreaterThan);
3178 bool TrueWhenLessThan =
3181 bool TrueWhenEqual =
3184 bool TrueWhenGreaterThan =
3197 if (TrueWhenLessThan)
3203 if (TrueWhenGreaterThan)
3213 auto *Bitcast = dyn_cast<BitCastInst>(Cmp.getOperand(0));
3218 Value *Op1 = Cmp.getOperand(1);
3219 Value *BCSrcOp = Bitcast->getOperand(0);
3220 Type *SrcType = Bitcast->getSrcTy();
3221 Type *DstType = Bitcast->getType();
3241 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(), 1));
3268 Type *XType =
X->getType();
3273 if (
auto *XVTy = dyn_cast<VectorType>(XType))
3287 if (!Cmp.getParent()->getParent()->hasFnAttribute(
3288 Attribute::NoImplicitFloat) &&
3313 if (Cmp.isEquality() &&
C->isAllOnes() && Bitcast->hasOneUse()) {
3314 if (
Value *NotBCSrcOp =
3325 if (Cmp.isEquality() &&
C->isZero() && Bitcast->hasOneUse() &&
3327 if (
auto *VecTy = dyn_cast<FixedVectorType>(
X->getType())) {
3346 auto *VecTy = cast<VectorType>(SrcType);
3347 auto *EltTy = cast<IntegerType>(VecTy->getElementType());
3348 if (
C->isSplat(EltTy->getBitWidth())) {
3356 Value *NewC = ConstantInt::get(EltTy,
C->trunc(EltTy->getBitWidth()));
3357 return new ICmpInst(Pred, Extract, NewC);
3370 if (
auto *BO = dyn_cast<BinaryOperator>(Cmp.getOperand(0)))
3374 if (
auto *SI = dyn_cast<SelectInst>(Cmp.getOperand(0)))
3378 if (
auto *ConstRHS = dyn_cast<ConstantInt>(Cmp.getOperand(1)))
3382 if (
auto *TI = dyn_cast<TruncInst>(Cmp.getOperand(0)))
3386 if (
auto *II = dyn_cast<IntrinsicInst>(Cmp.getOperand(0)))
3393 Value *Cmp0 = Cmp.getOperand(0);
3395 if (
C->isZero() && Cmp.isEquality() && Cmp0->
hasOneUse() &&
3397 m_ExtractValue<0>(m_Intrinsic<Intrinsic::ssub_with_overflow>(
3400 m_ExtractValue<0>(m_Intrinsic<Intrinsic::usub_with_overflow>(
3402 return new ICmpInst(Cmp.getPredicate(),
X,
Y);
3417 if (!Cmp.isEquality())
3422 Constant *
RHS = cast<Constant>(Cmp.getOperand(1));
3426 case Instruction::SRem:
3437 case Instruction::Add: {
3441 if (
Constant *C2 = dyn_cast<Constant>(BOp1)) {
3444 }
else if (
C.isZero()) {
3447 if (
Value *NegVal = dyn_castNegVal(BOp1))
3448 return new ICmpInst(Pred, BOp0, NegVal);
3449 if (
Value *NegVal = dyn_castNegVal(BOp0))
3450 return new ICmpInst(Pred, NegVal, BOp1);
3459 return new ICmpInst(Pred, BOp0, Neg);
3464 case Instruction::Xor:
3466 if (
Constant *BOC = dyn_cast<Constant>(BOp1)) {
3470 }
else if (
C.isZero()) {
3472 return new ICmpInst(Pred, BOp0, BOp1);
3476 case Instruction::Or: {
3488 case Instruction::UDiv:
3489 case Instruction::SDiv:
3499 return new ICmpInst(Pred, BOp0, BOp1);
3502 Instruction::Mul, BO->
getOpcode() == Instruction::SDiv, BOp1,
3503 Cmp.getOperand(1), BO);
3507 return new ICmpInst(Pred, YC, BOp0);
3511 if (BO->
getOpcode() == Instruction::UDiv &&
C.isZero()) {
3514 return new ICmpInst(NewPred, BOp1, BOp0);
3528 "Non-ctpop intrin in ctpop fold");
3569 case Intrinsic::abs:
3572 if (
C.isZero() ||
C.isMinSignedValue())
3576 case Intrinsic::bswap:
3579 ConstantInt::get(Ty,
C.byteSwap()));
3581 case Intrinsic::bitreverse:
3584 ConstantInt::get(Ty,
C.reverseBits()));
3586 case Intrinsic::ctlz:
3587 case Intrinsic::cttz: {
3596 unsigned Num =
C.getLimitedValue(
BitWidth);
3601 APInt Mask2 = IsTrailing
3605 ConstantInt::get(Ty, Mask2));
3610 case Intrinsic::ctpop: {
3613 bool IsZero =
C.isZero();
3622 case Intrinsic::fshl:
3623 case Intrinsic::fshr:
3625 const APInt *RotAmtC;
3631 ? ConstantInt::get(Ty,
C.rotr(*RotAmtC))
3632 : ConstantInt::get(Ty,
C.rotl(*RotAmtC)));
3636 case Intrinsic::umax:
3637 case Intrinsic::uadd_sat: {
3647 case Intrinsic::ssub_sat:
3652 case Intrinsic::usub_sat: {
3672 assert(Cmp.isEquality());
3675 Value *Op0 = Cmp.getOperand(0);
3676 Value *Op1 = Cmp.getOperand(1);
3677 const auto *IIOp0 = dyn_cast<IntrinsicInst>(Op0);
3678 const auto *IIOp1 = dyn_cast<IntrinsicInst>(Op1);
3679 if (!IIOp0 || !IIOp1 || IIOp0->getIntrinsicID() != IIOp1->getIntrinsicID())
3682 switch (IIOp0->getIntrinsicID()) {
3683 case Intrinsic::bswap:
3684 case Intrinsic::bitreverse:
3687 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
3688 case Intrinsic::fshl:
3689 case Intrinsic::fshr: {
3692 if (IIOp0->getOperand(0) != IIOp0->getOperand(1))
3694 if (IIOp1->getOperand(0) != IIOp1->getOperand(1))
3696 if (IIOp0->getOperand(2) == IIOp1->getOperand(2))
3697 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
3703 unsigned OneUses = IIOp0->hasOneUse() + IIOp1->hasOneUse();
3708 Builder.
CreateSub(IIOp0->getOperand(2), IIOp1->getOperand(2));
3710 Op0->
getType(), IIOp0->getIntrinsicID(),
3711 {IIOp0->getOperand(0), IIOp0->getOperand(0), SubAmt});
3712 return new ICmpInst(Pred, IIOp1->getOperand(0), CombinedRotate);
3729 if (
auto *II = dyn_cast<IntrinsicInst>(Cmp.getOperand(0))) {
3730 switch (II->getIntrinsicID()) {
3733 case Intrinsic::fshl:
3734 case Intrinsic::fshr:
3735 if (Cmp.isEquality() && II->getArgOperand(0) == II->getArgOperand(1)) {
3737 if (
C.isZero() ||
C.isAllOnes())
3738 return new ICmpInst(Pred, II->getArgOperand(0), Cmp.getOperand(1));
3752 case Instruction::Xor:
3756 case Instruction::And:
3760 case Instruction::Or:
3764 case Instruction::Mul:
3768 case Instruction::Shl:
3772 case Instruction::LShr:
3773 case Instruction::AShr:
3777 case Instruction::SRem:
3781 case Instruction::UDiv:
3785 case Instruction::SDiv:
3789 case Instruction::Sub:
3793 case Instruction::Add:
3840 "This function only works with usub_sat and uadd_sat for now!");
3841 case Intrinsic::uadd_sat:
3844 case Intrinsic::usub_sat:
3867 SatValCheck ? Instruction::BinaryOps::Or : Instruction::BinaryOps::And;
3869 std::optional<ConstantRange> Combination;
3870 if (CombiningOp == Instruction::BinaryOps::Or)
3882 Combination->getEquivalentICmp(EquivPred, EquivInt, EquivOffset);
3887 ConstantInt::get(Op1->
getType(), EquivInt));
3900 case Intrinsic::uadd_sat:
3901 case Intrinsic::usub_sat:
3903 Pred, cast<SaturatingInst>(II),
C,
Builder))
3906 case Intrinsic::ctpop: {
3913 if (Cmp.isEquality())
3919 case Intrinsic::ctpop: {
3931 case Intrinsic::ctlz: {
3934 unsigned Num =
C.getLimitedValue();
3942 unsigned Num =
C.getLimitedValue();
3949 case Intrinsic::cttz: {
3971 case Intrinsic::ssub_sat:
3995 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
3996 Constant *RHSC = dyn_cast<Constant>(Op1);
4002 case Instruction::PHI:
4006 case Instruction::IntToPtr:
4015 case Instruction::Load:
4018 dyn_cast<GetElementPtrInst>(LHSI->
getOperand(0)))
4034 auto SimplifyOp = [&](
Value *
Op,
bool SelectCondIsTrue) ->
Value * {
4038 SI->getCondition(), Pred,
Op,
RHS,
DL, SelectCondIsTrue))
4039 return ConstantInt::get(
I.getType(), *Impl);
4044 Value *Op1 = SimplifyOp(SI->getOperand(1),
true);
4046 CI = dyn_cast<ConstantInt>(Op1);
4048 Value *Op2 = SimplifyOp(SI->getOperand(2),
false);
4050 CI = dyn_cast<ConstantInt>(Op2);
4059 bool Transform =
false;
4062 else if (Op1 || Op2) {
4064 if (SI->hasOneUse())
4067 else if (CI && !CI->
isZero())
4086 unsigned Depth = 0) {
4089 if (V->getType()->getScalarSizeInBits() == 1)
4097 switch (
I->getOpcode()) {
4098 case Instruction::ZExt:
4101 case Instruction::SExt:
4105 case Instruction::And:
4106 case Instruction::Or:
4113 case Instruction::Xor:
4123 case Instruction::Select:
4127 case Instruction::Shl:
4130 case Instruction::LShr:
4133 case Instruction::AShr:
4137 case Instruction::Add:
4143 case Instruction::Sub:
4149 case Instruction::Call: {
4150 if (
auto *II = dyn_cast<IntrinsicInst>(
I)) {
4151 switch (II->getIntrinsicID()) {
4154 case Intrinsic::umax:
4155 case Intrinsic::smax:
4156 case Intrinsic::umin:
4157 case Intrinsic::smin:
4162 case Intrinsic::bitreverse:
4252 auto IsLowBitMask = [&]() {
4270 auto Check = [&]() {
4288 auto Check = [&]() {
4307 if (!IsLowBitMask())
4326 const APInt *C0, *C1;
4343 const APInt &MaskedBits = *C0;
4344 assert(MaskedBits != 0 &&
"shift by zero should be folded away already.");
4365 auto *XType =
X->getType();
4366 const unsigned XBitWidth = XType->getScalarSizeInBits();
4368 assert(
BitWidth.ugt(MaskedBits) &&
"shifts should leave some bits untouched");
4399 !
I.getOperand(0)->hasOneUse())
4424 assert(NarrowestTy ==
I.getOperand(0)->getType() &&
4425 "We did not look past any shifts while matching XShift though.");
4426 bool HadTrunc = WidestTy !=
I.getOperand(0)->getType();
4433 auto XShiftOpcode = XShift->
getOpcode();
4434 if (XShiftOpcode == YShift->
getOpcode())
4437 Value *
X, *XShAmt, *
Y, *YShAmt;
4444 if (!isa<Constant>(
X) && !isa<Constant>(
Y)) {
4446 if (!
match(
I.getOperand(0),
4472 unsigned MaximalPossibleTotalShiftAmount =
4475 APInt MaximalRepresentableShiftAmount =
4477 if (MaximalRepresentableShiftAmount.
ult(MaximalPossibleTotalShiftAmount))
4481 auto *NewShAmt = dyn_cast_or_null<Constant>(
4486 if (NewShAmt->getType() != WidestTy) {
4496 if (!
match(NewShAmt,
4498 APInt(WidestBitWidth, WidestBitWidth))))
4503 auto CanFold = [NewShAmt, WidestBitWidth, NarrowestShift, SQ,
4509 ? NewShAmt->getSplatValue()
4512 if (NewShAmtSplat &&
4518 if (
auto *
C = dyn_cast<Constant>(NarrowestShift->getOperand(0))) {
4522 unsigned MaxActiveBits = Known.
getBitWidth() - MinLeadZero;
4523 if (MaxActiveBits <= 1)
4529 if (
auto *
C = dyn_cast<Constant>(WidestShift->
getOperand(0))) {
4533 unsigned MaxActiveBits = Known.
getBitWidth() - MinLeadZero;
4534 if (MaxActiveBits <= 1)
4537 if (NewShAmtSplat) {
4540 if (AdjNewShAmt.
ule(MinLeadZero))
4554 Value *T0 = XShiftOpcode == Instruction::BinaryOps::LShr
4576 if (!
I.isEquality() &&
4586 NeedNegation =
false;
4589 NeedNegation =
true;
4595 if (
I.isEquality() &&
4611 bool MulHadOtherUses =
Mul && !
Mul->hasOneUse();
4612 if (MulHadOtherUses)
4617 ? Intrinsic::umul_with_overflow
4618 : Intrinsic::smul_with_overflow,
4625 if (MulHadOtherUses)
4634 if (MulHadOtherUses)
4660 Type *Ty =
X->getType();
4674 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
4698 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
4733 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
4749 return new ICmpInst(PredOut, Op0, Op1);
4761 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
4817 return new ICmpInst(NewPred, Op1, Zero);
4826 return new ICmpInst(NewPred, Op0, Zero);
4830 bool NoOp0WrapProblem =
false, NoOp1WrapProblem =
false;
4831 bool Op0HasNUW =
false, Op1HasNUW =
false;
4832 bool Op0HasNSW =
false, Op1HasNSW =
false;
4836 bool &HasNSW,
bool &HasNUW) ->
bool {
4837 if (isa<OverflowingBinaryOperator>(BO)) {
4843 }
else if (BO.
getOpcode() == Instruction::Or) {
4851 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr;
4855 NoOp0WrapProblem = hasNoWrapProblem(*BO0, Pred, Op0HasNSW, Op0HasNUW);
4859 NoOp1WrapProblem = hasNoWrapProblem(*BO1, Pred, Op1HasNSW, Op1HasNUW);
4864 if ((
A == Op1 ||
B == Op1) && NoOp0WrapProblem)
4870 if ((
C == Op0 ||
D == Op0) && NoOp1WrapProblem)
4875 if (
A &&
C && (
A ==
C ||
A ==
D ||
B ==
C ||
B ==
D) && NoOp0WrapProblem &&
4883 }
else if (
A ==
D) {
4887 }
else if (
B ==
C) {
4968 if (
A &&
C && NoOp0WrapProblem && NoOp1WrapProblem &&
4970 const APInt *AP1, *AP2;
4978 if (AP1Abs.
uge(AP2Abs)) {
4979 APInt Diff = *AP1 - *AP2;
4982 A, C3,
"", Op0HasNUW && Diff.
ule(*AP1), Op0HasNSW);
4985 APInt Diff = *AP2 - *AP1;
4988 C, C3,
"", Op1HasNUW && Diff.
ule(*AP2), Op1HasNSW);
5007 if (BO0 && BO0->
getOpcode() == Instruction::Sub) {
5011 if (BO1 && BO1->
getOpcode() == Instruction::Sub) {
5017 if (
A == Op1 && NoOp0WrapProblem)
5020 if (
C == Op0 && NoOp1WrapProblem)
5040 if (
B &&
D &&
B ==
D && NoOp0WrapProblem && NoOp1WrapProblem)
5044 if (
A &&
C &&
A ==
C && NoOp0WrapProblem && NoOp1WrapProblem)
5051 if (
Constant *RHSC = dyn_cast<Constant>(Op1))
5052 if (RHSC->isNotMinSignedValue())
5053 return new ICmpInst(
I.getSwappedPredicate(),
X,
5081 if (NonZero && BO0 && BO1 && Op0HasNSW && Op1HasNSW)
5088 if (NonZero && BO0 && BO1 && Op0HasNUW && Op1HasNUW)
5098 else if (BO1 && BO1->
getOpcode() == Instruction::SRem &&
5128 case Instruction::Add:
5129 case Instruction::Sub:
5130 case Instruction::Xor: {
5137 if (
C->isSignMask()) {
5143 if (BO0->
getOpcode() == Instruction::Xor &&
C->isMaxSignedValue()) {
5145 NewPred =
I.getSwappedPredicate(NewPred);
5151 case Instruction::Mul: {
5152 if (!
I.isEquality())
5160 if (
unsigned TZs =
C->countr_zero()) {
5166 return new ICmpInst(Pred, And1, And2);
5171 case Instruction::UDiv:
5172 case Instruction::LShr:
5177 case Instruction::SDiv:
5183 case Instruction::AShr:
5188 case Instruction::Shl: {
5189 bool NUW = Op0HasNUW && Op1HasNUW;
5190 bool NSW = Op0HasNSW && Op1HasNSW;
5193 if (!NSW &&
I.isSigned())
5258 auto IsCondKnownTrue = [](
Value *Val) -> std::optional<bool> {
5260 return std::nullopt;
5265 return std::nullopt;
5269 if (!CmpXZ.has_value() && !CmpYZ.has_value())
5271 if (!CmpXZ.has_value()) {
5277 if (CmpYZ.has_value())
5301 if (!MinMaxCmpXZ.has_value()) {
5309 if (!MinMaxCmpXZ.has_value())
5325 return FoldIntoCmpYZ();
5352 return FoldIntoCmpYZ();
5361 return FoldIntoCmpYZ();
5383 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5387 if (
I.isEquality()) {
5422 Type *Ty =
A->getType();
5425 ConstantInt::get(Ty, 2))
5427 ConstantInt::get(Ty, 1));
5434 if (!
I.isEquality())
5437 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5441 if (
A == Op1 ||
B == Op1) {
5442 Value *OtherVal =
A == Op1 ?
B :
A;
5485 Value *OtherVal =
A == Op0 ?
B :
A;
5492 Value *
X =
nullptr, *
Y =
nullptr, *Z =
nullptr;
5498 }
else if (
A ==
D) {
5502 }
else if (
B ==
C) {
5506 }
else if (
B ==
D) {
5533 (Op0->
hasOneUse() || Op1->hasOneUse())) {
5538 MaskC->
countr_one() ==
A->getType()->getScalarSizeInBits())
5544 const APInt *AP1, *AP2;
5553 if (ShAmt < TypeBits && ShAmt != 0) {
5558 return new ICmpInst(NewPred,
Xor, ConstantInt::get(
A->getType(), CmpVal));
5568 if (ShAmt < TypeBits && ShAmt != 0) {
5572 I.getName() +
".mask");
5586 unsigned ASize = cast<IntegerType>(
A->getType())->getPrimitiveSizeInBits();
5588 if (ShAmt < ASize) {
5611 A->getType()->getScalarSizeInBits() ==
BitWidth * 2 &&
5612 (
I.getOperand(0)->hasOneUse() ||
I.getOperand(1)->hasOneUse())) {
5617 Add, ConstantInt::get(
A->getType(),
C.shl(1)));
5641 m_OneUse(m_Intrinsic<Intrinsic::fshr>(
5661 std::optional<bool> IsZero = std::nullopt;
5705 unsigned SrcBits =
X->getType()->getScalarSizeInBits();
5709 Constant *MaskC = ConstantInt::get(
X->getType(),
C->zext(SrcBits));
5717 Constant *MaskC = ConstantInt::get(
X->getType(), (*
C + 1).zext(SrcBits));
5722 if (
auto *II = dyn_cast<IntrinsicInst>(
X)) {
5723 if (II->getIntrinsicID() == Intrinsic::cttz ||
5724 II->getIntrinsicID() == Intrinsic::ctlz) {
5725 unsigned MaxRet = SrcBits;
5745 assert(isa<CastInst>(ICmp.
getOperand(0)) &&
"Expected cast for operand 0");
5746 auto *CastOp0 = cast<CastInst>(ICmp.
getOperand(0));
5751 bool IsSignedExt = CastOp0->getOpcode() == Instruction::SExt;
5752 bool IsSignedCmp = ICmp.
isSigned();
5757 bool IsZext0 = isa<ZExtInst>(ICmp.
getOperand(0));
5758 bool IsZext1 = isa<ZExtInst>(ICmp.
getOperand(1));
5760 if (IsZext0 != IsZext1) {
5765 if (ICmp.
isEquality() &&
X->getType()->isIntOrIntVectorTy(1) &&
5766 Y->getType()->isIntOrIntVectorTy(1))
5773 auto *NonNegInst0 = dyn_cast<PossiblyNonNegInst>(ICmp.
getOperand(0));
5774 auto *NonNegInst1 = dyn_cast<PossiblyNonNegInst>(ICmp.
getOperand(1));
5776 bool IsNonNeg0 = NonNegInst0 && NonNegInst0->hasNonNeg();
5777 bool IsNonNeg1 = NonNegInst1 && NonNegInst1->hasNonNeg();
5779 if ((IsZext0 && IsNonNeg0) || (IsZext1 && IsNonNeg1))
5786 Type *XTy =
X->getType(), *YTy =
Y->getType();
5793 IsSignedExt ? Instruction::SExt : Instruction::ZExt;
5809 if (IsSignedCmp && IsSignedExt)
5822 Type *SrcTy = CastOp0->getSrcTy();
5830 if (IsSignedExt && IsSignedCmp)
5842 if (IsSignedCmp || !IsSignedExt || !isa<ConstantInt>(
C))
5861 Value *SimplifiedOp0 = simplifyIntToPtrRoundTripCast(ICmp.
getOperand(0));
5862 Value *SimplifiedOp1 = simplifyIntToPtrRoundTripCast(ICmp.
getOperand(1));
5863 if (SimplifiedOp0 || SimplifiedOp1)
5865 SimplifiedOp0 ? SimplifiedOp0 : ICmp.
getOperand(0),
5866 SimplifiedOp1 ? SimplifiedOp1 : ICmp.
getOperand(1));
5868 auto *CastOp0 = dyn_cast<CastInst>(ICmp.
getOperand(0));
5874 Value *Op0Src = CastOp0->getOperand(0);
5875 Type *SrcTy = CastOp0->getSrcTy();
5876 Type *DestTy = CastOp0->getDestTy();
5880 auto CompatibleSizes = [&](
Type *SrcTy,
Type *DestTy) {
5881 if (isa<VectorType>(SrcTy)) {
5882 SrcTy = cast<VectorType>(SrcTy)->getElementType();
5883 DestTy = cast<VectorType>(DestTy)->getElementType();
5887 if (CastOp0->getOpcode() == Instruction::PtrToInt &&
5888 CompatibleSizes(SrcTy, DestTy)) {
5889 Value *NewOp1 =
nullptr;
5890 if (
auto *PtrToIntOp1 = dyn_cast<PtrToIntOperator>(ICmp.
getOperand(1))) {
5891 Value *PtrSrc = PtrToIntOp1->getOperand(0);
5893 NewOp1 = PtrToIntOp1->getOperand(0);
5894 }
else if (
auto *RHSC = dyn_cast<Constant>(ICmp.
getOperand(1))) {
5912 case Instruction::Add:
5913 case Instruction::Sub:
5915 case Instruction::Mul:
5928 case Instruction::Add:
5933 case Instruction::Sub:
5938 case Instruction::Mul:
5947 bool IsSigned,
Value *LHS,
5951 if (OrigI.
isCommutative() && isa<Constant>(LHS) && !isa<Constant>(RHS))
5961 if (
auto *LHSTy = dyn_cast<VectorType>(
LHS->
getType()))
5976 Result->takeName(&OrigI);
5981 Result->takeName(&OrigI);
5983 if (
auto *Inst = dyn_cast<Instruction>(Result)) {
5985 Inst->setHasNoSignedWrap();
5987 Inst->setHasNoUnsignedWrap();
6010 const APInt *OtherVal,
6014 if (!isa<IntegerType>(MulVal->
getType()))
6017 auto *MulInstr = dyn_cast<Instruction>(MulVal);
6020 assert(MulInstr->getOpcode() == Instruction::Mul);
6022 auto *
LHS = cast<ZExtInst>(MulInstr->getOperand(0)),
6023 *
RHS = cast<ZExtInst>(MulInstr->getOperand(1));
6024 assert(
LHS->getOpcode() == Instruction::ZExt);
6025 assert(
RHS->getOpcode() == Instruction::ZExt);
6029 Type *TyA =
A->getType(), *TyB =
B->getType();
6031 WidthB = TyB->getPrimitiveSizeInBits();
6034 if (WidthB > WidthA) {
6049 if (
TruncInst *TI = dyn_cast<TruncInst>(U)) {
6052 if (TruncWidth > MulWidth)
6056 if (BO->getOpcode() != Instruction::And)
6058 if (
ConstantInt *CI = dyn_cast<ConstantInt>(BO->getOperand(1))) {
6059 const APInt &CVal = CI->getValue();
6075 switch (
I.getPredicate()) {
6082 if (MaxVal.
eq(*OtherVal))
6092 if (MaxVal.
eq(*OtherVal))
6106 if (WidthA < MulWidth)
6108 if (WidthB < MulWidth)
6111 I.getModule(), Intrinsic::umul_with_overflow, MulType);
6123 if (
TruncInst *TI = dyn_cast<TruncInst>(U)) {
6124 if (TI->getType()->getPrimitiveSizeInBits() == MulWidth)
6129 assert(BO->getOpcode() == Instruction::And);
6131 ConstantInt *CI = cast<ConstantInt>(BO->getOperand(1));
6167 switch (
I.getPredicate()) {
6198 assert(DI && UI &&
"Instruction not defined\n");
6209 auto *Usr = cast<Instruction>(U);
6210 if (Usr != UI && !
DT.
dominates(DB, Usr->getParent()))
6221 auto *BI = dyn_cast_or_null<BranchInst>(BB->
getTerminator());
6222 if (!BI || BI->getNumSuccessors() != 2)
6224 auto *IC = dyn_cast<ICmpInst>(BI->getCondition());
6225 if (!IC || (IC->getOperand(0) != SI && IC->getOperand(1) != SI))
6272 const unsigned SIOpd) {
6273 assert((SIOpd == 1 || SIOpd == 2) &&
"Invalid select operand!");
6275 BasicBlock *Succ = SI->getParent()->getTerminator()->getSuccessor(1);
6289 SI->replaceUsesOutsideBlock(SI->getOperand(SIOpd), SI->getParent());
6299 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6348 if (!isa<Constant>(Op0) && Op0Min == Op0Max)
6350 if (!isa<Constant>(Op1) && Op1Min == Op1Max)
6358 if (!Cmp.hasOneUse())
6367 if (!isMinMaxCmp(
I)) {
6372 if (Op1Min == Op0Max)
6377 if (*CmpC == Op0Min + 1)
6379 ConstantInt::get(Op1->getType(), *CmpC - 1));
6389 if (Op1Max == Op0Min)
6394 if (*CmpC == Op0Max - 1)
6396 ConstantInt::get(Op1->getType(), *CmpC + 1));
6406 if (Op1Min == Op0Max)
6410 if (*CmpC == Op0Min + 1)
6412 ConstantInt::get(Op1->getType(), *CmpC - 1));
6417 if (Op1Max == Op0Min)
6421 if (*CmpC == Op0Max - 1)
6423 ConstantInt::get(Op1->getType(), *CmpC + 1));
6437 if (Op0Max.
ult(Op1Min) || Op0Min.ugt(Op1Max))
6444 APInt Op0KnownZeroInverted = ~Op0Known.Zero;
6450 *LHSC != Op0KnownZeroInverted)
6456 Type *XTy =
X->getType();
6458 APInt C2 = Op0KnownZeroInverted;
6459 APInt C2Pow2 = (C2 & ~(*C1 - 1)) + *C1;
6465 auto *CmpC = ConstantInt::get(XTy, Log2C2 - Log2C1);
6475 (Op0Known & Op1Known) == Op0Known)
6481 if (Op0Max.
ult(Op1Min))
6483 if (Op0Min.uge(Op1Max))
6488 if (Op0Min.ugt(Op1Max))
6490 if (Op0Max.
ule(Op1Min))
6495 if (Op0Max.
slt(Op1Min))
6497 if (Op0Min.sge(Op1Max))
6502 if (Op0Min.sgt(Op1Max))
6504 if (Op0Max.
sle(Op1Min))
6509 assert(!isa<ConstantInt>(Op1) &&
"ICMP_SGE with ConstantInt not folded!");
6510 if (Op0Min.sge(Op1Max))
6512 if (Op0Max.
slt(Op1Min))
6514 if (Op1Min == Op0Max)
6518 assert(!isa<ConstantInt>(Op1) &&
"ICMP_SLE with ConstantInt not folded!");
6519 if (Op0Max.
sle(Op1Min))
6521 if (Op0Min.sgt(Op1Max))
6523 if (Op1Max == Op0Min)
6527 assert(!isa<ConstantInt>(Op1) &&
"ICMP_UGE with ConstantInt not folded!");
6528 if (Op0Min.uge(Op1Max))
6530 if (Op0Max.
ult(Op1Min))
6532 if (Op1Min == Op0Max)
6536 assert(!isa<ConstantInt>(Op1) &&
"ICMP_ULE with ConstantInt not folded!");
6537 if (Op0Max.
ule(Op1Min))
6539 if (Op0Min.ugt(Op1Max))
6541 if (Op1Max == Op0Min)
6551 return new ICmpInst(
I.getUnsignedPredicate(), Op0, Op1);
6583 bool IsSExt = ExtI->
getOpcode() == Instruction::SExt;
6585 auto CreateRangeCheck = [&] {
6600 }
else if (!IsSExt || HasOneUse) {
6605 return CreateRangeCheck();
6607 }
else if (IsSExt ?
C->isAllOnes() :
C->isOne()) {
6615 }
else if (!IsSExt || HasOneUse) {
6620 return CreateRangeCheck();
6634 Instruction::ICmp, Pred1,
X,
6644std::optional<std::pair<CmpInst::Predicate, Constant *>>
6648 "Only for relational integer predicates.");
6654 bool WillIncrement =
6659 auto ConstantIsOk = [WillIncrement, IsSigned](
ConstantInt *
C) {
6660 return WillIncrement ? !
C->isMaxValue(IsSigned) : !
C->isMinValue(IsSigned);
6663 Constant *SafeReplacementConstant =
nullptr;
6664 if (
auto *CI = dyn_cast<ConstantInt>(
C)) {
6666 if (!ConstantIsOk(CI))
6667 return std::nullopt;
6668 }
else if (
auto *FVTy = dyn_cast<FixedVectorType>(
Type)) {
6669 unsigned NumElts = FVTy->getNumElements();
6670 for (
unsigned i = 0; i != NumElts; ++i) {
6671 Constant *Elt =
C->getAggregateElement(i);
6673 return std::nullopt;
6675 if (isa<UndefValue>(Elt))
6680 auto *CI = dyn_cast<ConstantInt>(Elt);
6681 if (!CI || !ConstantIsOk(CI))
6682 return std::nullopt;
6684 if (!SafeReplacementConstant)
6685 SafeReplacementConstant = CI;
6687 }
else if (isa<VectorType>(
C->getType())) {
6689 Value *SplatC =
C->getSplatValue();
6690 auto *CI = dyn_cast_or_null<ConstantInt>(SplatC);
6692 if (!CI || !ConstantIsOk(CI))
6693 return std::nullopt;
6696 return std::nullopt;
6703 if (
C->containsUndefOrPoisonElement()) {
6704 assert(SafeReplacementConstant &&
"Replacement constant not set");
6711 Constant *OneOrNegOne = ConstantInt::get(
Type, WillIncrement ? 1 : -1,
true);
6714 return std::make_pair(NewPred, NewC);
6726 Value *Op0 =
I.getOperand(0);
6727 Value *Op1 =
I.getOperand(1);
6728 auto *Op1C = dyn_cast<Constant>(Op1);
6732 auto FlippedStrictness =
6734 if (!FlippedStrictness)
6737 return new ICmpInst(FlippedStrictness->first, Op0, FlippedStrictness->second);
6755 I.setName(
I.getName() +
".not");
6766 Value *
A =
I.getOperand(0), *
B =
I.getOperand(1);
6767 assert(
A->getType()->isIntOrIntVectorTy(1) &&
"Bools only");
6773 switch (
I.getPredicate()) {
6782 switch (
I.getPredicate()) {
6792 switch (
I.getPredicate()) {
6801 return BinaryOperator::CreateXor(
A,
B);
6809 return BinaryOperator::CreateAnd(Builder.
CreateNot(
A),
B);
6817 return BinaryOperator::CreateAnd(Builder.
CreateNot(
B),
A);
6825 return BinaryOperator::CreateOr(Builder.
CreateNot(
A),
B);
6833 return BinaryOperator::CreateOr(Builder.
CreateNot(
B),
A);
6889 Value *
LHS = Cmp.getOperand(0), *
RHS = Cmp.getOperand(1);
6894 if (
auto *
I = dyn_cast<Instruction>(V))
6895 I->copyIRFlags(&Cmp);
6896 Module *M = Cmp.getModule();
6906 return createCmpReverse(Pred, V1, V2);
6910 return createCmpReverse(Pred, V1,
RHS);
6914 return createCmpReverse(Pred,
LHS, V2);
6939 Constant *ScalarC =
C->getSplatValue(
true);
6958 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6962 auto UAddOvResultPat = m_ExtractValue<0>(
6964 if (
match(Op0, UAddOvResultPat) &&
6973 UAddOv = cast<ExtractValueInst>(Op0)->getAggregateOperand();
6974 else if (
match(Op1, UAddOvResultPat) &&
6977 UAddOv = cast<ExtractValueInst>(Op1)->getAggregateOperand();
6985 if (!
I.getOperand(0)->getType()->isPointerTy() ||
6987 I.getParent()->getParent(),
6988 I.getOperand(0)->getType()->getPointerAddressSpace())) {
6994 Op->isLaunderOrStripInvariantGroup()) {
6996 Op->getOperand(0),
I.getOperand(1));
7008 if (
I.getType()->isVectorTy())
7030 auto *LHSTy = dyn_cast<FixedVectorType>(
LHS->
getType());
7031 if (!LHSTy || !LHSTy->getElementType()->isIntegerTy())
7034 LHSTy->getNumElements() * LHSTy->getElementType()->getIntegerBitWidth();
7036 if (!
DL.isLegalInteger(NumBits))
7040 auto *ScalarTy = Builder.
getIntNTy(NumBits);
7055 if (
auto *
GEP = dyn_cast<GEPOperator>(Op0))
7059 if (
auto *SI = dyn_cast<SelectInst>(Op0))
7063 if (
auto *
MinMax = dyn_cast<MinMaxIntrinsic>(Op0))
7094 bool IsIntMinPosion =
C->isAllOnesValue();
7106 CxtI, IsIntMinPosion
7109 X, ConstantInt::get(
X->getType(),
SMin + 1)));
7115 CxtI, IsIntMinPosion
7118 X, ConstantInt::get(
X->getType(),
SMin)));
7131 auto CheckUGT1 = [](
const APInt &Divisor) {
return Divisor.ugt(1); };
7146 auto CheckNE0 = [](
const APInt &Shift) {
return !Shift.isZero(); };
7164 bool Changed =
false;
7166 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7173 if (Op0Cplxity < Op1Cplxity) {
7188 if (
Value *V = dyn_castNegVal(SelectTrue)) {
7189 if (V == SelectFalse)
7192 else if (
Value *V = dyn_castNegVal(SelectFalse)) {
7193 if (V == SelectTrue)
7234 if (
SelectInst *SI = dyn_cast<SelectInst>(
I.user_back())) {
7292 if (
I.isCommutative()) {
7293 if (
auto Pair = matchSymmetricPair(
I.getOperand(0),
I.getOperand(1))) {
7317 (Op0->
hasOneUse() || Op1->hasOneUse())) {
7333 assert(Op1->getType()->isPointerTy() &&
"Comparing pointer with non-pointer?");
7362 bool ConsumesOp0, ConsumesOp1;
7365 (ConsumesOp0 || ConsumesOp1)) {
7368 assert(InvOp0 && InvOp1 &&
7369 "Mismatch between isFreeToInvert and getFreelyInverted");
7370 return new ICmpInst(
I.getSwappedPredicate(), InvOp0, InvOp1);
7377 isa<IntegerType>(
X->getType())) {
7382 if (AddI->
getOpcode() == Instruction::Add &&
7383 OptimizeOverflowCheck(Instruction::Add,
false,
X,
Y, *AddI,
7384 Result, Overflow)) {
7402 if ((
I.isUnsigned() ||
I.isEquality()) &&
7405 Y->getType()->getScalarSizeInBits() == 1 &&
7406 (Op0->
hasOneUse() || Op1->hasOneUse())) {
7413 unsigned ShiftOpc = ShiftI->
getOpcode();
7414 if ((ExtOpc == Instruction::ZExt && ShiftOpc == Instruction::LShr) ||
7415 (ExtOpc == Instruction::SExt && ShiftOpc == Instruction::AShr)) {
7444 if (
auto *EVI = dyn_cast<ExtractValueInst>(Op0))
7445 if (
auto *ACXI = dyn_cast<AtomicCmpXchgInst>(EVI->getAggregateOperand()))
7446 if (EVI->getIndices()[0] == 0 && ACXI->getCompareOperand() == Op1 &&
7453 if (
I.getType()->isVectorTy())
7463 return Changed ? &
I :
nullptr;
7477 if (MantissaWidth == -1)
return nullptr;
7481 bool LHSUnsigned = isa<UIToFPInst>(LHSI);
7483 if (
I.isEquality()) {
7485 bool IsExact =
false;
7486 APSInt RHSCvt(IntWidth, LHSUnsigned);
7495 if (*
RHS != RHSRoundInt) {
7515 if ((
int)IntWidth > MantissaWidth) {
7517 int Exp = ilogb(*
RHS);
7520 if (MaxExponent < (
int)IntWidth - !LHSUnsigned)
7526 if (MantissaWidth <= Exp && Exp <= (
int)IntWidth - !LHSUnsigned)
7535 assert(!
RHS->isNaN() &&
"NaN comparison not already folded!");
7538 switch (
I.getPredicate()) {
7628 APSInt RHSInt(IntWidth, LHSUnsigned);
7631 if (!
RHS->isZero()) {
7645 if (
RHS->isNegative())
7651 if (
RHS->isNegative())
7657 if (
RHS->isNegative())
7664 if (!
RHS->isNegative())
7670 if (
RHS->isNegative())
7676 if (
RHS->isNegative())
7682 if (
RHS->isNegative())
7689 if (!
RHS->isNegative())
7743 if (
C->isNegative())
7744 Pred =
I.getSwappedPredicate();
7759 if (!
C->isPosZero()) {
7760 if (!
C->isSmallestNormalized())
7773 switch (
I.getPredicate()) {
7799 switch (
I.getPredicate()) {
7824 assert(!
I.hasNoNaNs() &&
"fcmp should have simplified");
7829 assert(!
I.hasNoNaNs() &&
"fcmp should have simplified");
7843 return replacePredAndOp0(&
I,
I.getPredicate(),
X);
7852 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7857 Pred =
I.getSwappedPredicate();
7866 return new FCmpInst(Pred, Op0, Zero,
"", &
I);
7870 bool Changed =
false;
7881 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7888 assert(OpType == Op1->getType() &&
"fcmp with different-typed operands?");
7912 if (
I.isCommutative()) {
7913 if (
auto Pair = matchSymmetricPair(
I.getOperand(0),
I.getOperand(1))) {
7935 return new FCmpInst(
I.getSwappedPredicate(),
X,
Y,
"", &
I);
7948 if (
SelectInst *SI = dyn_cast<SelectInst>(
I.user_back())) {
8017 Type *IntTy =
X->getType();
8029 case Instruction::Select:
8039 case Instruction::PHI:
8043 case Instruction::SIToFP:
8044 case Instruction::UIToFP:
8048 case Instruction::FDiv:
8052 case Instruction::Load:
8053 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(LHSI->
getOperand(0)))
8054 if (
auto *GV = dyn_cast<GlobalVariable>(
GEP->getOperand(0)))
8056 cast<LoadInst>(LHSI),
GEP, GV,
I))
8070 return new FCmpInst(
I.getSwappedPredicate(),
X, NegC,
"", &
I);
8089 X->getType()->getScalarType()->getFltSemantics();
8125 Constant *NewC = ConstantFP::get(
X->getType(), TruncC);
8139 if (
auto *VecTy = dyn_cast<VectorType>(OpType))
8151 Value *CanonLHS =
nullptr, *CanonRHS =
nullptr;
8152 match(Op0, m_Intrinsic<Intrinsic::canonicalize>(
m_Value(CanonLHS)));
8153 match(Op1, m_Intrinsic<Intrinsic::canonicalize>(
m_Value(CanonRHS)));
8156 if (CanonLHS == Op1)
8157 return new FCmpInst(Pred, Op1, Op1,
"", &
I);
8160 if (CanonRHS == Op0)
8161 return new FCmpInst(Pred, Op0, Op0,
"", &
I);
8164 if (CanonLHS && CanonRHS)
8165 return new FCmpInst(Pred, CanonLHS, CanonRHS,
"", &
I);
8168 if (
I.getType()->isVectorTy())
8172 return Changed ? &
I :
nullptr;
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu AMDGPU Register Bank Select
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
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 Instruction * foldICmpUSubSatOrUAddSatWithConstant(ICmpInst::Predicate Pred, SaturatingInst *II, const APInt &C, InstCombiner::BuilderTy &Builder)
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 Value * foldICmpWithLowBitMaskedVal(ICmpInst::Predicate Pred, Value *Op0, Value *Op1, const SimplifyQuery &Q, InstCombiner &IC)
Some comparisons can be simplified.
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 Instruction * foldICmpShlOne(ICmpInst &Cmp, Instruction *Shl, const APInt &C)
Fold icmp (shl 1, Y), C.
static bool isChainSelectCmpBranch(const SelectInst *SI)
Return true when the instruction sequence within a block is select-cmp-br.
static Instruction * foldICmpInvariantGroup(ICmpInst &I)
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 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 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 * foldICmpXorXX(ICmpInst &I, const SimplifyQuery &Q, InstCombinerImpl &IC)
static Instruction * processUMulZExtIdiom(ICmpInst &I, Value *MulVal, const APInt *OtherVal, InstCombinerImpl &IC)
Recognize and process idiom involving test for multiplication overflow.
static Instruction * transformToIndexedCompare(GEPOperator *GEPLHS, Value *RHS, ICmpInst::Predicate Cond, const DataLayout &DL, InstCombiner &IC)
Converts (CMP GEPLHS, RHS) if this change would make RHS a constant.
static Instruction * foldFCmpFNegCommonOp(FCmpInst &I)
static bool canRewriteGEPAsOffset(Value *Start, Value *Base, 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 * 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 * 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 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 * 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 Value * foldICmpWithTruncSignExtendedVal(ICmpInst &I, InstCombiner::BuilderTy &Builder)
Some comparisons can be simplified.
static Value * rewriteGEPAsOffset(Value *Start, Value *Base, 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 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.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
mir Rename Register Operands
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
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 SymbolRef::Type getType(const Symbol *Sym)
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.
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
FPClassTest classify() const
Return the FPClassTest which will return true for the value.
opStatus roundToIntegral(roundingMode RM)
Class for arbitrary precision integers.
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.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
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.
APInt trunc(unsigned width) const
Truncate to new width.
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
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.
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.
APInt sadd_ov(const APInt &RHS, bool &Overflow) const
bool intersects(const APInt &RHS) const
This operation tests if there are any pairs of corresponding bits between this APInt and RHS that are...
bool eq(const APInt &RHS) const
Equality comparison.
APInt sdiv(const APInt &RHS) const
Signed division function for APInt.
bool sle(const APInt &RHS) const
Signed less or equal comparison.
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.
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.
bool slt(const APInt &RHS) const
Signed less than comparison.
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.
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.
an instruction to allocate memory on the stack
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Class to represent array types.
LLVM Basic Block Representation.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
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...
unsigned getNoWrapKind() const
Returns one of OBO::NoSignedWrap or OBO::NoUnsignedWrap.
Instruction::BinaryOps getBinaryOp() const
Returns the binary operation underlying the intrinsic.
static BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name, BasicBlock::iterator InsertBefore)
Construct a binary instruction, given the opcode and the two operands.
BinaryOps getOpcode() const
static BinaryOperator * CreateNot(Value *Op, const Twine &Name, BasicBlock::iterator InsertBefore)
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, BasicBlock::iterator InsertBefore)
This class is the base class for the comparison instructions.
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate getStrictPredicate() const
For example, SGE -> SGT, SLE -> SLT, ULE -> ULT, UGE -> UGT.
bool isEquality() const
Determine if this is an equals/not equals predicate.
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.
Predicate getNonStrictPredicate() const
For example, SGT -> SGE, SLT -> SLE, ULT -> ULE, UGT -> UGE.
static CmpInst * Create(OtherOps Op, Predicate Pred, Value *S1, Value *S2, const Twine &Name, BasicBlock::iterator InsertBefore)
Construct a compare instruction, given the opcode, the predicate and the two operands.
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.
Predicate getFlippedStrictnessPredicate() const
For predicate of kind "is X or equal to 0" returns the predicate "is X".
Predicate getFlippedSignednessPredicate()
For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->Failed assert.
bool isIntPredicate() const
static Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getPointerBitCastOrAddrSpaceCast(Constant *C, Type *Ty)
Create a BitCast or AddrSpaceCast for a pointer type depending on the address space.
static Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getNot(Constant *C)
static Constant * getXor(Constant *C1, Constant *C2)
static Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getNeg(Constant *C, bool HasNSW=false)
static Constant * getCompare(unsigned short pred, Constant *C1, Constant *C2, bool OnlyIfReduced=false)
Return an ICmp or FCmp comparison operator constant expression.
static 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 ConstantInt * getTrue(LLVMContext &Context)
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
static 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 ConstantInt * getBool(LLVMContext &Context, bool V)
This class represents a range of values.
ConstantRange add(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an addition of a value in this ran...
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...
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.
ConstantRange difference(const ConstantRange &CR) const
Subtract the specified range from this range (aka relative complement of the sets).
bool isEmptySet() const
Return true if this set contains no members.
static 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...
ConstantRange inverse() const
Return a new range that is the logical not of the current set.
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...
ConstantRange intersectWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the intersection of this range with another range.
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 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 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 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 Constant * replaceUndefsWith(Constant *C, Constant *Replacement)
Try to replace undefined constant C or undefined elements in C with Replacement.
static Constant * getAllOnesValue(Type *Ty)
bool isAllOnesValue() const
Return true if this is the value that would be returned by getAllOnesValue.
const APInt & getUniqueInteger() const
If C is a constant integer then return its value, otherwise C must be a vector of constant integers,...
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
bool isLegalInteger(uint64_t Width) const
Returns true if the specified type is known to be a native integer type supported by the CPU.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
unsigned getPointerTypeSizeInBits(Type *) const
Layout pointer size, in bits, based on the type.
IntegerType * getIndexType(LLVMContext &C, unsigned AddressSpace) const
Returns the type of a GEP index in AddressSpace.
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Type * getSmallestLegalIntType(LLVMContext &C, unsigned Width=0) const
Returns the smallest integer type with size at least as big as Width bits.
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
ArrayRef< BranchInst * > conditionsFor(const Value *V) const
Access the list of branches which affect this value.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
This instruction compares its operands according to the predicate given to the constructor.
bool isInBounds() const
Test whether this is an inbounds GEP, as defined by LangRef.html.
Type * getSourceElementType() const
Value * getPointerOperand()
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
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
bool hasDefinitiveInitializer() const
hasDefinitiveInitializer - Whether the global variable has an initializer, and any other instances of...
This instruction compares its operands according to the predicate given to the constructor.
static bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
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.
Common base class shared among various IRBuilders.
CallInst * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with 1 operand which is mangled on its type.
Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
Value * CreateICmpSGT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")
Return a vector value that contains.
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
ConstantInt * getTrue()
Get the constant value for i1 true.
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateNSWAdd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateInBoundsGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="")
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
Value * createIsFPClass(Value *FPNum, unsigned Test)
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Value * CreateCmp(CmpInst::Predicate Pred, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateICmpUGT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
ConstantInt * getFalse()
Get the constant value for i1 false.
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="")
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Value * CreateIsNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg == 0.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
ConstantInt * getInt(const APInt &AI)
Get a constant integer value.
Value * CreateURem(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
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 * FoldOpIntoSelect(Instruction &Op, SelectInst *SI, bool FoldWithMultiUse=false)
Given an instruction with a select as one operand and a constant as the other operand,...
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...
bool SimplifyDemandedBits(Instruction *I, unsigned Op, const APInt &DemandedMask, KnownBits &Known, unsigned Depth=0) override
This form of SimplifyDemandedBits simplifies the specified instruction operand if possible,...
Instruction * foldOpIntoPhi(Instruction &I, PHINode *PN)
Given a binary operator, cast instruction, or select which has a PHI node as operand #0,...
Value * insertRangeTest(Value *V, const APInt &Lo, const APInt &Hi, bool isSigned, bool Inside)
Emit a computation of: (V >= Lo && V < Hi) if Inside is true, otherwise (V < Lo || V >= Hi).
Instruction * foldICmpBinOp(ICmpInst &Cmp, const SimplifyQuery &SQ)
Try to fold icmp (binop), X or icmp X, (binop).
Instruction * foldICmpSubConstant(ICmpInst &Cmp, BinaryOperator *Sub, const APInt &C)
Fold icmp (sub X, Y), C.
Instruction * foldICmpInstWithConstantNotInt(ICmpInst &Cmp)
Handle icmp with constant (but not simple integer constant) RHS.
Instruction * foldICmpWithMinMax(Instruction &I, MinMaxIntrinsic *MinMax, Value *Z, ICmpInst::Predicate Pred)
Fold icmp Pred min|max(X, Y), Z.
Instruction * foldGEPICmp(GEPOperator *GEPLHS, Value *RHS, ICmpInst::Predicate Cond, Instruction &I)
Fold comparisons between a GEP instruction and something else.
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.
Value * foldMultiplicationOverflowCheck(ICmpInst &Cmp)
Fold (-1 u/ x) u< y ((x * y) ?/ x) != y to @llvm.
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 * 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 * foldCmpLoadFromIndexedGlobal(LoadInst *LI, GetElementPtrInst *GEP, GlobalVariable *GV, 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 * 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.
Constant * getLosslessTrunc(Constant *C, Type *TruncTy, unsigned ExtOp)
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 * foldICmpAddOpConst(Value *X, const APInt &C, ICmpInst::Predicate Pred)
Fold "icmp pred (X+C), X".
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 * foldICmpAndShift(ICmpInst &Cmp, BinaryOperator *And, const APInt &C1, const APInt &C2)
Fold icmp (and (sh X, Y), C2), C1.
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)
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 * foldICmpCommutative(ICmpInst::Predicate Pred, Value *Op0, Value *Op1, ICmpInst &CxtI)
Instruction * visitICmpInst(ICmpInst &I)
Instruction * foldSelectICmp(ICmpInst::Predicate Pred, SelectInst *SI, Value *RHS, const 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)
The core instruction combiner logic.
OverflowResult computeOverflowForSignedSub(const Value *LHS, const Value *RHS, const Instruction *CxtI) const
static bool isCanonicalPredicate(CmpInst::Predicate Pred)
Predicate canonicalization reduces the number of patterns that need to be matched by other transforms...
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.
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, unsigned Depth=0, const Instruction *CxtI=nullptr)
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.
static std::optional< std::pair< CmpInst::Predicate, Constant * > > getFlippedStrictnessPredicateAndConstant(CmpInst::Predicate Pred, Constant *C)
OverflowResult computeOverflowForUnsignedSub(const Value *LHS, const Value *RHS, const Instruction *CxtI) const
bool canFreelyInvertAllUsersOf(Instruction *V, Value *IgnoredUser)
Given i1 V, can every user of V be freely adapted if V is changed to !V ? InstCombine's freelyInvertA...
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
void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth, 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
unsigned ComputeMaxSignificantBits(const Value *Op, unsigned Depth=0, const Instruction *CxtI=nullptr) const
bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
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.
bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
const BasicBlock * getParent() const
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 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.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This class represents min/max intrinsics.
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, BasicBlock::iterator InsertBefore)
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, BasicBlock::iterator InsertBefore, Instruction *MDFrom=nullptr)
A vector that has set insertion semantics.
size_type size() const
Determine the number of elements in the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
bool contains(const key_type &key) const
Check if the SetVector contains the given key.
This instruction constructs a fixed permutation of two input vectors.
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.
Class to represent struct types.
This class represents a truncation of integer types.
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getIntegerBitWidth() const
const fltSemantics & getFltSemantics() const
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.
static IntegerType * getInt1Ty(LLVMContext &C)
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isPPC_FP128Ty() const
Return true if this is powerpc long double.
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
int getFPMantissaWidth() const
Return the width of the mantissa of this type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isIEEELikeFPTy() const
Return true if this is a well-behaved IEEE-like type, which has a IEEE compatible layout as defined b...
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
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.
const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr) const
Accumulate the constant offset this value has compared to a base pointer.
bool hasOneUse() const
Return true if there is exactly one use of this value.
iterator_range< user_iterator > users()
bool hasNUsesOrMore(unsigned N) const
Return true if this value has N uses or more.
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< use_iterator > uses()
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
static VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
constexpr ScalarTy getFixedValue() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
APInt RoundingUDiv(const APInt &A, const APInt &B, APInt::Rounding RM)
Return A unsign-divided by B, rounded by the given rounding mode.
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.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
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)
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.
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)
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
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.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
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)
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.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
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)
CastOperator_match< OpTy, Instruction::Trunc > m_Trunc(const OpTy &Op)
Matches Trunc.
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()...
cst_pred_ty< is_zero_int > m_ZeroInt()
Match an integer 0 or a vector with all elements equal to 0.
apint_match m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
NoWrapTrunc_match< OpTy, TruncInst::NoSignedWrap > m_NSWTrunc(const OpTy &Op)
Matches trunc nsw.
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate > m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)
OneUse_match< T > m_OneUse(const T &SubPattern)
BinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub > m_Neg(const ValTy &V)
Matches a 'Neg' as 'sub 0, V'.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
match_combine_and< class_match< Constant >, match_unless< constantexpr_match > > m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
CastInst_match< OpTy, FPExtInst > m_FPExt(const OpTy &Op)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
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)
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.
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate, true > m_c_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
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.
match_combine_or< CastOperator_match< OpTy, Instruction::Trunc >, OpTy > m_TruncOrSelf(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
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)
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.
apfloat_match m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
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< cst_pred_ty< is_all_ones >, ValTy, Instruction::Xor, true > m_Not(const ValTy &V)
Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
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.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
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.
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
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...
bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return true if the given value is known to have exactly one bit set when defined.
Constant * ConstantFoldExtractValueInstruction(Constant *Agg, ArrayRef< unsigned > Idxs)
Attempt to constant fold an extractvalue instruction with the specified operands and indices.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for an Add, fold the result or return null.
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.
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
Constant * ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op, const DataLayout &DL)
Attempt to constant fold a unary operation with the specified operand.
SelectPatternFlavor
Specific patterns of select instructions we can match.
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures, unsigned MaxUsesToExplore=0)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
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...
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.
Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
Value * simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an ICmpInst, fold the result or return null.
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.
@ UMin
Unsigned integer min implemented in terms of select(cmp()).
@ Or
Bitwise or logical OR of integers.
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ SMax
Signed integer max implemented in terms of select(cmp()).
@ And
Bitwise or logical AND of integers.
@ SMin
Signed integer min implemented in terms of select(cmp()).
@ UMax
Unsigned integer max implemented in terms of select(cmp()).
void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
DWARFExpression::Operation Op
constexpr unsigned BitWidth
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...
bool decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate &Pred, Value *&X, APInt &Mask, bool LookThroughTrunc=true)
Decompose an icmp into the form ((X & Mask) pred 0) if possible.
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
bool isKnownNeverNaN(const Value *V, unsigned Depth, const SimplifyQuery &SQ)
Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...
bool isKnownPositive(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the given value is known be positive (i.e.
Value * simplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q)
Given operands for an FCmpInst, fold the result or return null.
bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the give value is known to be non-negative.
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.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static constexpr roundingMode rmNearestTiesToEven
static constexpr roundingMode rmTowardZero
This callback is used in conjunction with PointerMayBeCaptured.
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.
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.
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.
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
const DomConditionCache * DC
A MapVector that performs no allocations if smaller than a certain size.