42#define DEBUG_TYPE "instcombine"
50 bool IsSigned =
false) {
53 Result = In1.
sadd_ov(In2, Overflow);
55 Result = In1.
uadd_ov(In2, Overflow);
63 bool IsSigned =
false) {
66 Result = In1.
ssub_ov(In2, Overflow);
68 Result = In1.
usub_ov(In2, Overflow);
76 for (
auto *U :
I.users())
98 }
else if (
C.isAllOnes()) {
125 if (LI->
isVolatile() || !GV || !GV->isConstant() ||
126 !GV->hasDefinitiveInitializer())
130 TypeSize EltSize =
DL.getTypeStoreSize(EltTy);
146 if (!ConstOffset.
ult(Stride))
165 uint64_t ArrayElementCount =
168 if (ArrayElementCount >
CLOpts.maxarray_size)
171 enum { Overdefined = -3, Undefined = -2 };
180 int FirstTrueElement = Undefined, SecondTrueElement = Undefined;
184 int FirstFalseElement = Undefined, SecondFalseElement = Undefined;
192 int TrueRangeEnd = Undefined, FalseRangeEnd = Undefined;
197 uint64_t MagicBitvector = 0;
201 for (
unsigned i = 0, e = ArrayElementCount; i != e; ++i,
Offset += Stride) {
222 if (TrueRangeEnd == (
int)i - 1)
224 if (FalseRangeEnd == (
int)i - 1)
241 if (FirstTrueElement == Undefined)
242 FirstTrueElement = TrueRangeEnd = i;
245 if (SecondTrueElement == Undefined)
246 SecondTrueElement = i;
248 SecondTrueElement = Overdefined;
251 if (TrueRangeEnd == (
int)i - 1)
254 TrueRangeEnd = Overdefined;
258 if (FirstFalseElement == Undefined)
259 FirstFalseElement = FalseRangeEnd = i;
262 if (SecondFalseElement == Undefined)
263 SecondFalseElement = i;
265 SecondFalseElement = Overdefined;
268 if (FalseRangeEnd == (
int)i - 1)
271 FalseRangeEnd = Overdefined;
276 if (i < 64 && IsTrueForElt)
277 MagicBitvector |= 1ULL << i;
282 if ((i & 8) == 0 && i >= 64 && SecondTrueElement == Overdefined &&
283 SecondFalseElement == Overdefined && TrueRangeEnd == Overdefined &&
284 FalseRangeEnd == Overdefined)
298 auto MaskIdx = [&](
Value *Idx) {
302 Idx =
Builder.CreateAnd(Idx, Mask);
309 if (SecondTrueElement != Overdefined) {
312 if (FirstTrueElement == Undefined)
315 Value *FirstTrueIdx = ConstantInt::get(Idx->getType(), FirstTrueElement);
318 if (SecondTrueElement == Undefined)
323 Value *SecondTrueIdx = ConstantInt::get(Idx->getType(), SecondTrueElement);
325 return BinaryOperator::CreateOr(
C1, C2);
330 if (SecondFalseElement != Overdefined) {
333 if (FirstFalseElement == Undefined)
336 Value *FirstFalseIdx = ConstantInt::get(Idx->getType(), FirstFalseElement);
339 if (SecondFalseElement == Undefined)
344 Value *SecondFalseIdx =
345 ConstantInt::get(Idx->getType(), SecondFalseElement);
347 return BinaryOperator::CreateAnd(
C1, C2);
352 if (TrueRangeEnd != Overdefined) {
353 assert(TrueRangeEnd != FirstTrueElement &&
"Should emit single compare");
357 if (FirstTrueElement) {
359 Idx =
Builder.CreateAdd(Idx, Offs);
363 ConstantInt::get(Idx->getType(), TrueRangeEnd - FirstTrueElement + 1);
368 if (FalseRangeEnd != Overdefined) {
369 assert(FalseRangeEnd != FirstFalseElement &&
"Should emit single compare");
372 if (FirstFalseElement) {
374 Idx =
Builder.CreateAdd(Idx, Offs);
378 ConstantInt::get(Idx->getType(), FalseRangeEnd - FirstFalseElement);
391 if (ArrayElementCount <= Idx->
getType()->getIntegerBitWidth())
394 Ty =
DL.getSmallestLegalIntType(
Init->getContext(), ArrayElementCount);
399 V =
Builder.CreateLShr(ConstantInt::get(Ty, MagicBitvector), V);
400 V =
Builder.CreateAnd(ConstantInt::get(Ty, 1), V);
425 while (!WorkList.
empty()) {
428 while (!WorkList.
empty()) {
429 if (Explored.
size() >= 100)
447 if (!
GEP->isInBounds() ||
count_if(
GEP->indices(), IsNonConst) > 1)
455 if (WorkList.
back() == V) {
471 for (
auto *PN : PHIs)
472 for (
Value *
Op : PN->incoming_values())
480 for (
Value *Val : Explored) {
486 if (Inst ==
Base || Inst ==
PHI || !Inst || !
PHI ||
490 if (
PHI->getParent() == Inst->getParent())
500 bool Before =
true) {
508 I = &*std::next(
I->getIterator());
509 Builder.SetInsertPoint(
I);
514 BasicBlock &Entry =
A->getParent()->getEntryBlock();
515 Builder.SetInsertPoint(Entry.getFirstInsertionPt());
537 Base->getContext(),
DL.getIndexTypeSizeInBits(Start->getType()));
543 for (
Value *Val : Explored) {
551 PHI->getName() +
".idx",
PHI->getIterator());
556 for (
Value *Val : Explored) {
565 NewInsts[
GEP] = OffsetV;
567 NewInsts[
GEP] = Builder.CreateAdd(
568 Op, OffsetV,
GEP->getOperand(0)->getName() +
".add",
580 for (
Value *Val : Explored) {
587 for (
unsigned I = 0,
E =
PHI->getNumIncomingValues();
I <
E; ++
I) {
588 Value *NewIncoming =
PHI->getIncomingValue(
I);
590 auto It = NewInsts.
find(NewIncoming);
591 if (It != NewInsts.
end())
592 NewIncoming = It->second;
599 for (
Value *Val : Explored) {
605 Value *NewVal = Builder.CreateGEP(Builder.getInt8Ty(),
Base, NewInsts[Val],
606 Val->getName() +
".ptr", NW);
613 return NewInsts[Start];
699 if (
Base.Ptr == RHS && CanFold(
Base.LHSNW) && !
Base.isExpensive()) {
703 EmitGEPOffsets(
Base.LHSGEPs,
Base.LHSNW, IdxTy,
true);
711 RHS->getType()->getPointerAddressSpace())) {
742 if (GEPLHS->
getOperand(0) != GEPRHS->getOperand(0)) {
743 bool IndicesTheSame =
746 GEPRHS->getPointerOperand()->getType() &&
750 if (GEPLHS->
getOperand(i) != GEPRHS->getOperand(i)) {
751 IndicesTheSame =
false;
757 if (IndicesTheSame &&
765 if (GEPLHS->
isInBounds() && GEPRHS->isInBounds() &&
767 (GEPRHS->hasAllConstantIndices() || GEPRHS->hasOneUse()) &&
771 Value *LOffset = EmitGEPOffset(GEPLHS);
772 Value *ROffset = EmitGEPOffset(GEPRHS);
779 if (LHSIndexTy != RHSIndexTy) {
782 ROffset =
Builder.CreateTrunc(ROffset, LHSIndexTy);
784 LOffset =
Builder.CreateTrunc(LOffset, RHSIndexTy);
793 if (GEPLHS->
getOperand(0) == GEPRHS->getOperand(0) &&
797 unsigned NumDifferences = 0;
798 unsigned DiffOperand = 0;
799 for (
unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i)
800 if (GEPLHS->
getOperand(i) != GEPRHS->getOperand(i)) {
802 Type *RHSType = GEPRHS->getOperand(i)->getType();
813 if (NumDifferences++)
818 if (NumDifferences == 0)
826 Value *RHSV = GEPRHS->getOperand(DiffOperand);
827 return NewICmp(NW, LHSV, RHSV);
831 if (
Base.Ptr && !
Base.isExpensive()) {
833 bool DoFold = CanFold(
Base.LHSNW &
Base.RHSNW);
835 if (!DoFold &&
Base.Ptr->getType()->isPointerTy()) {
839 unsigned BW =
DL.getIndexTypeSizeInBits(GEPLHS->
getType());
844 DL, LOff,
true) ==
Base.Ptr &&
845 RHS->stripAndAccumulateConstantOffsets(
846 DL, ROff,
true) ==
Base.Ptr)
858 return NewICmp(
Base.LHSNW &
Base.RHSNW, L, R);
885 bool Captured =
false;
890 CmpCaptureTracker(
AllocaInst *Alloca) : Alloca(Alloca) {}
892 void tooManyUses()
override { Captured =
true; }
904 ICmps[ICmp] |= 1u << U->getOperandNo();
913 CmpCaptureTracker Tracker(Alloca);
915 if (Tracker.Captured)
919 for (
auto [ICmp,
Operands] : Tracker.ICmps) {
925 auto *Res = ConstantInt::get(ICmp->getType(),
951 assert(!!
C &&
"C should not be zero!");
967 ConstantInt::get(
X->getType(), -
C));
979 ConstantInt::get(
X->getType(),
SMax -
C));
990 ConstantInt::get(
X->getType(),
SMax - (
C - 1)));
999 assert(
I.isEquality() &&
"Cannot fold icmp gt/lt");
1002 if (
I.getPredicate() ==
I.ICMP_NE)
1004 return new ICmpInst(Pred, LHS, RHS);
1023 return getICmp(
I.ICMP_UGT,
A,
1024 ConstantInt::get(
A->getType(), AP2.
logBase2()));
1036 if (IsAShr && AP1 == AP2.
ashr(Shift)) {
1040 return getICmp(
I.ICMP_UGE,
A, ConstantInt::get(
A->getType(), Shift));
1041 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1042 }
else if (AP1 == AP2.
lshr(Shift)) {
1043 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1049 auto *TorF = ConstantInt::get(
I.getType(),
I.getPredicate() ==
I.ICMP_NE);
1058 assert(
I.isEquality() &&
"Cannot fold icmp gt/lt");
1061 if (
I.getPredicate() ==
I.ICMP_NE)
1063 return new ICmpInst(Pred, LHS, RHS);
1072 if (!AP1 && AP2TrailingZeros != 0)
1075 ConstantInt::get(
A->getType(), AP2.
getBitWidth() - AP2TrailingZeros));
1083 if (Shift > 0 && AP2.
shl(Shift) == AP1)
1084 return getICmp(
I.ICMP_EQ,
A, ConstantInt::get(
A->getType(), Shift));
1088 auto *TorF = ConstantInt::get(
I.getType(),
I.getPredicate() ==
I.ICMP_NE);
1117 if (NewWidth != 7 && NewWidth != 15 && NewWidth != 31)
1141 if (U == AddWithCst)
1159 I.getModule(), Intrinsic::sadd_with_overflow, NewType);
1167 Value *TruncA = Builder.CreateTrunc(
A, NewType,
A->getName() +
".trunc");
1168 Value *TruncB = Builder.CreateTrunc(
B, NewType,
B->getName() +
".trunc");
1169 CallInst *
Call = Builder.CreateCall(
F, {TruncA, TruncB},
"sadd");
1170 Value *
Add = Builder.CreateExtractValue(
Call, 0,
"sadd.result");
1188 if (!
I.isEquality())
1219 APInt(XBitWidth, XBitWidth - 1))))
1246 return new ICmpInst(Pred,
B, Cmp.getOperand(1));
1248 return new ICmpInst(Pred,
A, Cmp.getOperand(1));
1265 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1277 return new ICmpInst(Pred,
Y, Cmp.getOperand(1));
1283 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1286 if (BO0->hasNoUnsignedWrap() || BO0->hasNoSignedWrap()) {
1294 return new ICmpInst(Pred,
Y, Cmp.getOperand(1));
1299 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
1315 return new ICmpInst(Pred, Stripped,
1328 const APInt *Mask, *Neg;
1344 auto *NewAnd =
Builder.CreateAnd(Num, *Mask);
1347 return new ICmpInst(Pred, NewAnd, Zero);
1368 Value *Op0 = Cmp.getOperand(0), *Op1 = Cmp.getOperand(1);
1384 for (
Value *V : Phi->incoming_values()) {
1392 PHINode *NewPhi =
Builder.CreatePHI(Cmp.getType(), Phi->getNumOperands());
1393 for (
auto [V, Pred] :
zip(
Ops, Phi->blocks()))
1408 Value *
X = Cmp.getOperand(0), *
Y = Cmp.getOperand(1);
1441 if (Cmp.isEquality() || (IsSignBit &&
hasBranchUse(Cmp)))
1446 if (Cmp.hasOneUse() &&
1460 if (!
match(BI->getCondition(),
1465 if (
DT.dominates(Edge0, Cmp.getParent())) {
1466 if (
auto *V = handleDomCond(DomPred, DomC))
1470 if (
DT.dominates(Edge1, Cmp.getParent()))
1486 Type *SrcTy =
X->getType();
1488 SrcBits = SrcTy->getScalarSizeInBits();
1492 if (shouldChangeType(Trunc->
getType(), SrcTy)) {
1494 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy,
C.sext(SrcBits)));
1496 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy,
C.zext(SrcBits)));
1499 if (
C.isOne() &&
C.getBitWidth() > 1) {
1504 ConstantInt::get(V->getType(), 1));
1516 auto NewPred = (Pred == Cmp.ICMP_EQ) ? Cmp.ICMP_UGE : Cmp.ICMP_ULT;
1518 ConstantInt::get(SrcTy, DstBits - Pow2->
logBase2()));
1524 Pred,
Y, ConstantInt::get(SrcTy,
C.logBase2() - Pow2->
logBase2()));
1530 if (!SrcTy->isVectorTy() && shouldChangeType(DstBits, SrcBits)) {
1534 Constant *WideC = ConstantInt::get(SrcTy,
C.zext(SrcBits));
1543 if ((
Known.Zero |
Known.One).countl_one() >= SrcBits - DstBits) {
1545 APInt NewRHS =
C.zext(SrcBits);
1547 return new ICmpInst(Pred,
X, ConstantInt::get(SrcTy, NewRHS));
1559 DstBits == SrcBits - ShAmt) {
1576 bool YIsSExt =
false;
1579 unsigned NoWrapFlags =
cast<TruncInst>(Cmp.getOperand(0))->getNoWrapKind() &
1581 if (Cmp.isSigned()) {
1592 if (
X->getType() !=
Y->getType() &&
1593 (!Cmp.getOperand(0)->hasOneUse() || !Cmp.getOperand(1)->hasOneUse()))
1595 if (!isDesirableIntType(
X->getType()->getScalarSizeInBits()) &&
1596 isDesirableIntType(
Y->getType()->getScalarSizeInBits())) {
1598 Pred = Cmp.getSwappedPredicate(Pred);
1603 else if (!Cmp.isSigned() &&
1617 Type *TruncTy = Cmp.getOperand(0)->getType();
1622 if (isDesirableIntType(TruncBits) &&
1623 !isDesirableIntType(
X->getType()->getScalarSizeInBits()))
1646 bool TrueIfSigned =
false;
1663 if (
Xor->hasOneUse()) {
1665 if (!Cmp.isEquality() && XorC->
isSignMask()) {
1666 Pred = Cmp.getFlippedSignednessPredicate();
1667 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(),
C ^ *XorC));
1672 Pred = Cmp.getFlippedSignednessPredicate();
1673 Pred = Cmp.getSwappedPredicate(Pred);
1674 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(),
C ^ *XorC));
1681 if (*XorC == ~
C && (
C + 1).isPowerOf2())
1684 if (*XorC ==
C && (
C + 1).isPowerOf2())
1689 if (*XorC == -
C &&
C.isPowerOf2())
1691 ConstantInt::get(
X->getType(), ~
C));
1693 if (*XorC ==
C && (-
C).isPowerOf2())
1695 ConstantInt::get(
X->getType(), ~
C));
1717 const APInt *ShiftC;
1722 Type *XType =
X->getType();
1728 return new ICmpInst(Pred,
Add, ConstantInt::get(XType, Bound));
1737 if (!Shift || !Shift->
isShift())
1745 unsigned ShiftOpcode = Shift->
getOpcode();
1746 bool IsShl = ShiftOpcode == Instruction::Shl;
1749 APInt NewAndCst, NewCmpCst;
1750 bool AnyCmpCstBitsShiftedOut;
1751 if (ShiftOpcode == Instruction::Shl) {
1756 if (Cmp.isSigned() && (C2.
isNegative() ||
C1.isNegative()))
1759 NewCmpCst =
C1.lshr(*C3);
1760 NewAndCst = C2.
lshr(*C3);
1761 AnyCmpCstBitsShiftedOut = NewCmpCst.
shl(*C3) !=
C1;
1762 }
else if (ShiftOpcode == Instruction::LShr) {
1767 NewCmpCst =
C1.shl(*C3);
1768 NewAndCst = C2.
shl(*C3);
1769 AnyCmpCstBitsShiftedOut = NewCmpCst.
lshr(*C3) !=
C1;
1775 assert(ShiftOpcode == Instruction::AShr &&
"Unknown shift opcode");
1776 NewCmpCst =
C1.shl(*C3);
1777 NewAndCst = C2.
shl(*C3);
1778 AnyCmpCstBitsShiftedOut = NewCmpCst.
ashr(*C3) !=
C1;
1779 if (NewAndCst.
ashr(*C3) != C2)
1783 if (AnyCmpCstBitsShiftedOut) {
1793 Shift->
getOperand(0), ConstantInt::get(
And->getType(), NewAndCst));
1794 return new ICmpInst(Cmp.getPredicate(), NewAnd,
1795 ConstantInt::get(
And->getType(), NewCmpCst));
1802 if (Shift->
hasOneUse() &&
C1.isZero() && Cmp.isEquality() &&
1812 return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
1826 return new TruncInst(
And->getOperand(0), Cmp.getType());
1837 ConstantInt::get(
X->getType(), ~*C2));
1842 ConstantInt::get(
X->getType(), -*C2));
1845 if (!
And->hasOneUse())
1848 if (Cmp.isEquality() &&
C1.isZero()) {
1866 Constant *NegBOC = ConstantInt::get(
And->getType(), -NewC2);
1868 return new ICmpInst(NewPred,
X, NegBOC);
1882 (Cmp.isEquality() || (!
C1.isNegative() && !C2->
isNegative()))) {
1886 if (!Cmp.getType()->isVectorTy()) {
1887 Type *WideType = W->getType();
1889 Constant *ZextC1 = ConstantInt::get(WideType,
C1.zext(WideScalarBits));
1890 Constant *ZextC2 = ConstantInt::get(WideType, C2->
zext(WideScalarBits));
1892 return new ICmpInst(Cmp.getPredicate(), NewAnd, ZextC1);
1903 if (!Cmp.isSigned() &&
C1.isZero() &&
And->getOperand(0)->hasOneUse() &&
1910 unsigned UsesRemoved = 0;
1911 if (
And->hasOneUse())
1913 if (
Or->hasOneUse())
1920 if (UsesRemoved >= RequireUsesRemoved) {
1924 One,
Or->getName());
1926 return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
1940 if (!Cmp.getParent()->getParent()->hasFnAttribute(
1941 Attribute::NoImplicitFloat) &&
1944 Type *FPType = V->getType()->getScalarType();
1945 if (FPType->isIEEELikeFPTy() && (
C1.isZero() ||
C1 == *C2)) {
1946 APInt ExponentMask =
1948 if (*C2 == ExponentMask) {
1949 unsigned Mask =
C1.isZero()
1983 Constant *MinSignedC = ConstantInt::get(
1987 return new ICmpInst(NewPred,
X, MinSignedC);
2004 if (!Cmp.isEquality())
2014 if (
C.getBitWidth() > 1 && (
C.isZero() ||
C.isOne()) &&
2018 return new ICmpInst(Pred, MatchedX, Cmp.getOperand(1));
2022 return new TruncInst(MatchedX, Cmp.getType());
2026 if (
And->hasOneUse()) {
2027 Value *Trunc =
Builder.CreateTrunc(MatchedX, Cmp.getType());
2035 if (Cmp.getOperand(1) ==
Y &&
C.isNegatedPowerOf2()) {
2046 X->getType()->isIntOrIntVectorTy(1) && (
C.isZero() ||
C.isOne())) {
2052 return BinaryOperator::CreateAnd(TruncY,
X);
2070 const APInt *Addend, *Msk;
2074 APInt NewComperand = (
C - *Addend) & *Msk;
2075 Value *MaskA =
Builder.CreateAnd(
A, ConstantInt::get(
A->getType(), *Msk));
2077 ConstantInt::get(MaskA->
getType(), NewComperand));
2099 while (!WorkList.
empty()) {
2100 auto MatchOrOperatorArgument = [&](
Value *OrOperatorArgument) {
2103 if (
match(OrOperatorArgument,
2109 if (
match(OrOperatorArgument,
2119 Value *OrOperatorLhs, *OrOperatorRhs;
2121 if (!
match(CurrentValue,
2126 MatchOrOperatorArgument(OrOperatorRhs);
2127 MatchOrOperatorArgument(OrOperatorLhs);
2132 Value *LhsCmp = Builder.CreateICmp(Pred, CmpValues.
rbegin()->first,
2133 CmpValues.
rbegin()->second);
2135 for (
auto It = CmpValues.
rbegin() + 1; It != CmpValues.
rend(); ++It) {
2136 Value *RhsCmp = Builder.CreateICmp(Pred, It->first, It->second);
2137 LhsCmp = Builder.CreateBinOp(BOpc, LhsCmp, RhsCmp);
2153 ConstantInt::get(V->getType(), 1));
2156 Value *OrOp0 =
Or->getOperand(0), *OrOp1 =
Or->getOperand(1);
2163 Builder.CreateXor(OrOp1, ConstantInt::get(OrOp1->getType(),
C));
2164 return new ICmpInst(Pred, OrOp0, NewC);
2168 if (
match(OrOp1,
m_APInt(MaskC)) && Cmp.isEquality()) {
2169 if (*MaskC ==
C && (
C + 1).isPowerOf2()) {
2174 return new ICmpInst(Pred, OrOp0, OrOp1);
2181 if (
Or->hasOneUse()) {
2183 Constant *NewC = ConstantInt::get(
Or->getType(),
C ^ (*MaskC));
2195 Constant *NewC = ConstantInt::get(
X->getType(), TrueIfSigned ? 1 : 0);
2223 if (!Cmp.isEquality() || !
C.isZero() || !
Or->hasOneUse())
2254 if (
X ==
Mul->getOperand(1) && !Cmp.isSigned()) {
2256 bool IsSqr =
C == R * R;
2259 if (Cmp.isEquality() &&
2260 (
Mul->hasNoUnsignedWrap() || (
Mul->hasNoSignedWrap() &&
C.isZero()))) {
2268 return new ICmpInst(Pred,
X, ConstantInt::get(MulTy, R));
2273 if (
Mul->hasNoUnsignedWrap()) {
2276 return new ICmpInst(Pred,
X, ConstantInt::get(MulTy, R));
2290 return new ICmpInst(Cmp.getStrictPredicate(),
X,
2291 ConstantInt::get(MulTy, R));
2314 if (Cmp.isEquality()) {
2316 if (
Mul->hasNoSignedWrap() &&
C.srem(*MulC).isZero()) {
2317 Constant *NewC = ConstantInt::get(MulTy,
C.sdiv(*MulC));
2325 if (
C.urem(*MulC).isZero()) {
2328 if ((*MulC & 1).isOne() ||
Mul->hasNoUnsignedWrap()) {
2329 Constant *NewC = ConstantInt::get(MulTy,
C.udiv(*MulC));
2342 if (
C.isMinSignedValue() && MulC->
isAllOnes())
2348 NewC = ConstantInt::get(
2352 "Unexpected predicate");
2353 NewC = ConstantInt::get(
2358 NewC = ConstantInt::get(
2362 "Unexpected predicate");
2363 NewC = ConstantInt::get(
2368 return NewC ?
new ICmpInst(Pred,
X, NewC) :
nullptr;
2380 unsigned TypeBits =
C.getBitWidth();
2382 if (Cmp.isUnsigned()) {
2402 return new ICmpInst(Pred,
Y, ConstantInt::get(ShiftType, CLog2));
2403 }
else if (Cmp.isSigned() && C2->
isOne()) {
2404 Constant *BitWidthMinusOne = ConstantInt::get(ShiftType, TypeBits - 1);
2425 const APInt *ShiftVal;
2455 const APInt *ShiftAmt;
2461 unsigned TypeBits =
C.getBitWidth();
2462 if (ShiftAmt->
uge(TypeBits))
2474 APInt ShiftedC =
C.ashr(*ShiftAmt);
2475 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2478 C.ashr(*ShiftAmt).shl(*ShiftAmt) ==
C) {
2479 APInt ShiftedC =
C.ashr(*ShiftAmt);
2480 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2487 assert(!
C.isMinSignedValue() &&
"Unexpected icmp slt");
2488 APInt ShiftedC = (
C - 1).ashr(*ShiftAmt) + 1;
2489 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2499 APInt ShiftedC =
C.lshr(*ShiftAmt);
2500 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2503 C.lshr(*ShiftAmt).shl(*ShiftAmt) ==
C) {
2504 APInt ShiftedC =
C.lshr(*ShiftAmt);
2505 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2512 assert(
C.ugt(0) &&
"ult 0 should have been eliminated");
2513 APInt ShiftedC = (
C - 1).lshr(*ShiftAmt) + 1;
2514 return new ICmpInst(Pred,
X, ConstantInt::get(ShType, ShiftedC));
2518 if (Cmp.isEquality() && Shl->
hasOneUse()) {
2524 Constant *LShrC = ConstantInt::get(ShType,
C.lshr(*ShiftAmt));
2529 bool TrueIfSigned =
false;
2541 if (Cmp.isUnsigned() && Shl->
hasOneUse()) {
2543 if ((
C + 1).isPowerOf2() &&
2551 if (
C.isPowerOf2() &&
2581 Pred, ConstantInt::get(ShType->
getContext(),
C))) {
2582 CmpPred = FlippedStrictness->first;
2590 ConstantInt::get(TruncTy, RHSC.
ashr(*ShiftAmt).
trunc(TypeBits - Amt));
2592 Builder.CreateTrunc(
X, TruncTy,
"",
false,
2609 if (Cmp.isEquality() && Shr->
isExact() &&
C.isZero())
2610 return new ICmpInst(Pred,
X, Cmp.getOperand(1));
2612 bool IsAShr = Shr->
getOpcode() == Instruction::AShr;
2613 const APInt *ShiftValC;
2615 if (Cmp.isEquality())
2633 assert(ShiftValC->
uge(
C) &&
"Expected simplify of compare");
2634 assert((IsUGT || !
C.isZero()) &&
"Expected X u< 0 to simplify");
2636 unsigned CmpLZ = IsUGT ?
C.countl_zero() : (
C - 1).
countl_zero();
2644 const APInt *ShiftAmtC;
2650 unsigned TypeBits =
C.getBitWidth();
2652 if (ShAmtVal >= TypeBits || ShAmtVal == 0)
2655 bool IsExact = Shr->
isExact();
2663 (
C - 1).isPowerOf2() &&
C.countLeadingZeros() > ShAmtVal) {
2669 APInt ShiftedC = (
C - 1).shl(ShAmtVal) + 1;
2670 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2676 APInt ShiftedC =
C.shl(ShAmtVal);
2677 if (ShiftedC.
ashr(ShAmtVal) ==
C)
2678 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2682 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2683 if (!
C.isMaxSignedValue() && !(
C + 1).shl(ShAmtVal).isMinSignedValue() &&
2684 (ShiftedC + 1).ashr(ShAmtVal) == (
C + 1))
2685 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2691 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2692 if ((ShiftedC + 1).ashr(ShAmtVal) == (
C + 1) ||
2693 (
C + 1).shl(ShAmtVal).isMinSignedValue())
2694 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2701 if (
C.getBitWidth() > 2 &&
C.getNumSignBits() <= ShAmtVal) {
2711 }
else if (!IsAShr) {
2715 APInt ShiftedC =
C.shl(ShAmtVal);
2716 if (ShiftedC.
lshr(ShAmtVal) ==
C)
2717 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2721 APInt ShiftedC = (
C + 1).shl(ShAmtVal) - 1;
2722 if ((ShiftedC + 1).lshr(ShAmtVal) == (
C + 1))
2723 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy, ShiftedC));
2727 if (!Cmp.isEquality())
2735 assert(((IsAShr &&
C.shl(ShAmtVal).ashr(ShAmtVal) ==
C) ||
2736 (!IsAShr &&
C.shl(ShAmtVal).lshr(ShAmtVal) ==
C)) &&
2737 "Expected icmp+shr simplify did not occur.");
2742 return new ICmpInst(Pred,
X, ConstantInt::get(ShrTy,
C << ShAmtVal));
2748 Constant *Mask = ConstantInt::get(ShrTy, Val);
2750 return new ICmpInst(Pred,
And, ConstantInt::get(ShrTy,
C << ShAmtVal));
2767 const APInt *DivisorC;
2776 "ult X, 0 should have been simplified already.");
2781 if (!NormalizedC.
uge(DivisorC->
abs() - 1))
2804 const APInt *DivisorC;
2813 !
C.isStrictlyPositive()))
2819 Constant *MaskC = ConstantInt::get(Ty, SignMask | (*DivisorC - 1));
2823 return new ICmpInst(Pred,
And, ConstantInt::get(Ty,
C));
2850 assert(*C2 != 0 &&
"udiv 0, X should have been simplified already.");
2855 "icmp ugt X, UINT_MAX should have been simplified already.");
2857 ConstantInt::get(Ty, C2->
udiv(
C + 1)));
2862 assert(
C != 0 &&
"icmp ult X, 0 should have been simplified already.");
2864 ConstantInt::get(Ty, C2->
udiv(
C)));
2878 bool DivIsSigned = Div->
getOpcode() == Instruction::SDiv;
2888 if (Cmp.isEquality() && Div->
hasOneUse() &&
C.isSignBitSet() &&
2889 (!DivIsSigned ||
C.isMinSignedValue())) {
2890 Value *XBig =
Builder.CreateICmp(Pred,
X, ConstantInt::get(Ty,
C));
2891 Value *YOne =
Builder.CreateICmp(Pred,
Y, ConstantInt::get(Ty, 1));
2917 if (!Cmp.isEquality() && DivIsSigned != Cmp.isSigned()) {
2921 DivIsSigned =
false;
2940 bool ProdOV = (DivIsSigned ? Prod.
sdiv(*C2) : Prod.
udiv(*C2)) !=
C;
2953 int LoOverflow = 0, HiOverflow = 0;
2954 APInt LoBound, HiBound;
2959 HiOverflow = LoOverflow = ProdOV;
2968 LoBound = -(RangeSize - 1);
2969 HiBound = RangeSize;
2970 }
else if (
C.isStrictlyPositive()) {
2972 HiOverflow = LoOverflow = ProdOV;
2978 LoOverflow = HiOverflow = ProdOV ? -1 : 0;
2980 APInt DivNeg = -RangeSize;
2981 LoOverflow =
addWithOverflow(LoBound, HiBound, DivNeg,
true) ? -1 : 0;
2989 LoBound = RangeSize + 1;
2990 HiBound = -RangeSize;
2991 if (HiBound == *C2) {
2995 }
else if (
C.isStrictlyPositive()) {
2998 HiOverflow = LoOverflow = ProdOV ? -1 : 0;
3004 LoOverflow = HiOverflow = ProdOV;
3017 if (LoOverflow && HiOverflow)
3021 X, ConstantInt::get(Ty, LoBound));
3024 X, ConstantInt::get(Ty, HiBound));
3028 if (LoOverflow && HiOverflow)
3032 X, ConstantInt::get(Ty, LoBound));
3035 X, ConstantInt::get(Ty, HiBound));
3040 if (LoOverflow == +1)
3042 if (LoOverflow == -1)
3044 return new ICmpInst(Pred,
X, ConstantInt::get(Ty, LoBound));
3047 if (HiOverflow == +1)
3049 if (HiOverflow == -1)
3091 bool HasNSW =
Sub->hasNoSignedWrap();
3092 bool HasNUW =
Sub->hasNoUnsignedWrap();
3094 ((Cmp.isUnsigned() && HasNUW) || (Cmp.isSigned() && HasNSW)) &&
3096 return new ICmpInst(SwappedPred,
Y, ConstantInt::get(Ty, SubResult));
3104 if (Cmp.isEquality() &&
C.isZero() &&
3105 none_of((
Sub->users()), [](
const User *U) { return isa<PHINode>(U); }))
3113 if (!
Sub->hasOneUse())
3116 if (
Sub->hasNoSignedWrap()) {
3140 (*C2 & (
C - 1)) == (
C - 1))
3153 return new ICmpInst(SwappedPred,
Add, ConstantInt::get(Ty, ~
C));
3159 auto FoldConstant = [&](
bool Val) {
3160 Constant *Res = Val ? Builder.getTrue() : Builder.getFalse();
3167 switch (
Table.to_ulong()) {
3169 return FoldConstant(
false);
3171 return HasOneUse ? Builder.CreateNot(Builder.CreateOr(Op0, Op1)) :
nullptr;
3173 return HasOneUse ? Builder.CreateAnd(Builder.CreateNot(Op0), Op1) :
nullptr;
3175 return Builder.CreateNot(Op0);
3177 return HasOneUse ? Builder.CreateAnd(Op0, Builder.CreateNot(Op1)) :
nullptr;
3179 return Builder.CreateNot(Op1);
3181 return Builder.CreateXor(Op0, Op1);
3183 return HasOneUse ? Builder.CreateNot(Builder.CreateAnd(Op0, Op1)) :
nullptr;
3185 return Builder.CreateAnd(Op0, Op1);
3187 return HasOneUse ? Builder.CreateNot(Builder.CreateXor(Op0, Op1)) :
nullptr;
3191 return HasOneUse ? Builder.CreateOr(Builder.CreateNot(Op0), Op1) :
nullptr;
3195 return HasOneUse ? Builder.CreateOr(Op0, Builder.CreateNot(Op1)) :
nullptr;
3197 return Builder.CreateOr(Op0, Op1);
3199 return FoldConstant(
true);
3214 Cmp.getType() !=
A->getType() || Cmp.getType() !=
B->getType())
3217 std::bitset<4>
Table;
3218 auto ComputeTable = [&](
bool First,
bool Second) -> std::optional<bool> {
3222 auto *Val = Res->getType()->isVectorTy() ? Res->getSplatValue() : Res;
3226 return std::nullopt;
3229 for (
unsigned I = 0;
I < 4; ++
I) {
3230 bool First = (
I >> 1) & 1;
3231 bool Second =
I & 1;
3232 if (
auto Res = ComputeTable(
First, Second))
3254 const APInt *ShAmtC;
3262 return new ICmpInst(Pred,
A, ConstantInt::get(
A->getType(),
C));
3274 if (
Add->hasNoUnsignedWrap() &&
3277 APInt NewC =
C.usub_ov(*C2, Overflow);
3281 return new ICmpInst(Pred,
X, ConstantInt::get(Ty, NewC));
3286 if (
Add->hasNoSignedWrap() &&
3289 APInt NewC =
C.ssub_ov(*C2, Overflow);
3293 return new ICmpInst(ChosenPred,
X, ConstantInt::get(Ty, NewC));
3297 C.isNonNegative() && (
C - *C2).isNonNegative() &&
3300 .isAllNonNegative())
3302 ConstantInt::get(Ty,
C - *C2));
3307 if (Cmp.isSigned()) {
3308 if (
Lower.isSignMask())
3310 if (
Upper.isSignMask())
3313 if (
Lower.isMinValue())
3315 if (
Upper.isMinValue())
3348 if (!
Add->hasOneUse())
3363 ConstantInt::get(Ty,
C * 2));
3377 Builder.CreateAdd(
X, ConstantInt::get(Ty, *C2 -
C - 1)),
3378 ConstantInt::get(Ty, ~
C));
3383 Type *NewCmpTy = V->getType();
3385 if (shouldChangeType(Ty, NewCmpTy)) {
3396 :
Builder.CreateAdd(V, ConstantInt::get(NewCmpTy, EquivOffset)),
3397 ConstantInt::get(NewCmpTy, EquivInt));
3419 Value *EqualVal =
SI->getTrueValue();
3420 Value *UnequalVal =
SI->getFalseValue();
3443 auto FlippedStrictness =
3445 if (!FlippedStrictness)
3448 "basic correctness failure");
3449 RHS2 = FlippedStrictness->second;
3461 assert(
C &&
"Cmp RHS should be a constant int!");
3467 Value *OrigLHS, *OrigRHS;
3468 ConstantInt *C1LessThan, *C2Equal, *C3GreaterThan;
3469 if (Cmp.hasOneUse() &&
3472 assert(C1LessThan && C2Equal && C3GreaterThan);
3475 C1LessThan->
getValue(),
C->getValue(), Cmp.getPredicate());
3477 Cmp.getPredicate());
3479 C3GreaterThan->
getValue(),
C->getValue(), Cmp.getPredicate());
3490 if (TrueWhenLessThan)
3496 if (TrueWhenGreaterThan)
3511 Value *Op1 = Cmp.getOperand(1);
3512 Value *BCSrcOp = Bitcast->getOperand(0);
3513 Type *SrcType = Bitcast->getSrcTy();
3514 Type *DstType = Bitcast->getType();
3518 if (SrcType->isVectorTy() == DstType->isVectorTy() &&
3519 SrcType->getScalarSizeInBits() == DstType->getScalarSizeInBits()) {
3534 return new ICmpInst(Pred,
X, ConstantInt::get(
X->getType(), 1));
3561 Type *XType =
X->getType();
3564 if (!(XType->
isPPC_FP128Ty() || SrcType->isPPC_FP128Ty())) {
3579 Type *FPType = SrcType->getScalarType();
3580 if (!Cmp.getParent()->getParent()->hasFnAttribute(
3581 Attribute::NoImplicitFloat) &&
3582 Cmp.isEquality() && FPType->isIEEELikeFPTy()) {
3588 Builder.createIsFPClass(BCSrcOp, Mask));
3611 if (!
match(Cmp.getOperand(1),
m_APInt(
C)) || !DstType->isIntegerTy() ||
3612 !SrcType->isIntOrIntVectorTy())
3622 if (Cmp.isEquality() &&
C->isAllOnes() && Bitcast->hasOneUse()) {
3623 if (
Value *NotBCSrcOp =
3625 Value *Cast =
Builder.CreateBitCast(NotBCSrcOp, DstType);
3634 if (Cmp.isEquality() &&
C->isZero() && Bitcast->hasOneUse() &&
3637 Type *NewType =
Builder.getIntNTy(VecTy->getPrimitiveSizeInBits());
3657 if (
C->isSplat(EltTy->getBitWidth())) {
3663 Value *Extract =
Builder.CreateExtractElement(Vec, Mask[0]);
3664 Value *NewC = ConstantInt::get(EltTy,
C->trunc(EltTy->getBitWidth()));
3665 return new ICmpInst(Pred, Extract, NewC);
3703 if (
match(Cmp.getOperand(0),
3709 bool ValidPred =
true;
3727 X->getType()->getScalarType()->getFltSemantics();
3730 if (!Exp.isNegative() && Exp.sle(MaxExp + 1) &&
3732 int ExpVal =
static_cast<int>(Exp.getSExtValue());
3737 ConstantFP::get(
X->getType(), CmpConst));
3746 Value *Cmp0 = Cmp.getOperand(0);
3748 if (
C->isZero() && Cmp.isEquality() && Cmp0->
hasOneUse() &&
3755 return new ICmpInst(Cmp.getPredicate(),
X,
Y);
3770 if (!Cmp.isEquality())
3779 case Instruction::SRem:
3790 case Instruction::Add: {
3797 }
else if (
C.isZero()) {
3800 if (
Value *NegVal = dyn_castNegVal(BOp1))
3801 return new ICmpInst(Pred, BOp0, NegVal);
3802 if (
Value *NegVal = dyn_castNegVal(BOp0))
3803 return new ICmpInst(Pred, NegVal, BOp1);
3812 return new ICmpInst(Pred, BOp0, Neg);
3817 case Instruction::Xor:
3822 }
else if (
C.isZero()) {
3824 return new ICmpInst(Pred, BOp0, BOp1);
3827 case Instruction::Or: {
3848 Cond->getType() == Cmp.getType()) {
3886 case Instruction::UDiv:
3887 case Instruction::SDiv:
3897 return new ICmpInst(Pred, BOp0, BOp1);
3900 Instruction::Mul, BO->
getOpcode() == Instruction::SDiv, BOp1,
3901 Cmp.getOperand(1), BO);
3905 return new ICmpInst(Pred, YC, BOp0);
3909 if (BO->
getOpcode() == Instruction::UDiv &&
C.isZero()) {
3912 return new ICmpInst(NewPred, BOp1, BOp0);
3926 "Non-ctpop intrin in ctpop fold");
3961 Type *Ty =
II->getType();
3965 switch (
II->getIntrinsicID()) {
3966 case Intrinsic::abs:
3969 if (
C.isZero() ||
C.isMinSignedValue())
3970 return new ICmpInst(Pred,
II->getArgOperand(0), ConstantInt::get(Ty,
C));
3973 case Intrinsic::bswap:
3975 return new ICmpInst(Pred,
II->getArgOperand(0),
3976 ConstantInt::get(Ty,
C.byteSwap()));
3978 case Intrinsic::bitreverse:
3980 return new ICmpInst(Pred,
II->getArgOperand(0),
3981 ConstantInt::get(Ty,
C.reverseBits()));
3983 case Intrinsic::ctlz:
3984 case Intrinsic::cttz: {
3987 return new ICmpInst(Pred,
II->getArgOperand(0),
3993 unsigned Num =
C.getLimitedValue(
BitWidth);
3995 bool IsTrailing =
II->getIntrinsicID() == Intrinsic::cttz;
3998 APInt Mask2 = IsTrailing
4002 ConstantInt::get(Ty, Mask2));
4007 case Intrinsic::ctpop: {
4010 bool IsZero =
C.isZero();
4012 return new ICmpInst(Pred,
II->getArgOperand(0),
4019 case Intrinsic::fshl:
4020 case Intrinsic::fshr:
4021 if (
II->getArgOperand(0) ==
II->getArgOperand(1)) {
4022 const APInt *RotAmtC;
4026 return new ICmpInst(Pred,
II->getArgOperand(0),
4027 II->getIntrinsicID() == Intrinsic::fshl
4028 ? ConstantInt::get(Ty,
C.rotr(*RotAmtC))
4029 : ConstantInt::get(Ty,
C.rotl(*RotAmtC)));
4033 case Intrinsic::umax:
4034 case Intrinsic::uadd_sat: {
4037 if (
C.isZero() &&
II->hasOneUse()) {
4044 case Intrinsic::ssub_sat:
4049 if (
C.isZero() &&
II->getType()->getScalarSizeInBits() > 1)
4050 return new ICmpInst(Pred,
II->getArgOperand(0),
II->getArgOperand(1));
4052 case Intrinsic::usub_sat: {
4057 return new ICmpInst(NewPred,
II->getArgOperand(0),
II->getArgOperand(1));
4072 assert(Cmp.isEquality());
4075 Value *Op0 = Cmp.getOperand(0);
4076 Value *Op1 = Cmp.getOperand(1);
4079 if (!IIOp0 || !IIOp1 || IIOp0->getIntrinsicID() != IIOp1->getIntrinsicID())
4082 switch (IIOp0->getIntrinsicID()) {
4083 case Intrinsic::bswap:
4084 case Intrinsic::bitreverse:
4087 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
4088 case Intrinsic::fshl:
4089 case Intrinsic::fshr: {
4092 if (IIOp0->getOperand(0) != IIOp0->getOperand(1))
4094 if (IIOp1->getOperand(0) != IIOp1->getOperand(1))
4096 if (IIOp0->getOperand(2) == IIOp1->getOperand(2))
4097 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
4103 const unsigned BW = IIOp0->getType()->getScalarSizeInBits();
4104 unsigned OneUses = IIOp0->hasOneUse() + IIOp1->hasOneUse();
4113 Builder.CreateSub(IIOp0->getOperand(2), IIOp1->getOperand(2));
4114 Value *CombinedRotate = Builder.CreateIntrinsic(
4115 Op0->
getType(), IIOp0->getIntrinsicID(),
4116 {IIOp0->getOperand(0), IIOp0->getOperand(0), SubAmt});
4117 return new ICmpInst(Pred, IIOp1->getOperand(0), CombinedRotate);
4136 switch (
II->getIntrinsicID()) {
4139 case Intrinsic::fshl:
4140 case Intrinsic::fshr:
4141 if (Cmp.isEquality() &&
II->getArgOperand(0) ==
II->getArgOperand(1)) {
4143 if (
C.isZero() ||
C.isAllOnes())
4144 return new ICmpInst(Pred,
II->getArgOperand(0), Cmp.getOperand(1));
4158 case Instruction::Xor:
4162 case Instruction::And:
4166 case Instruction::Or:
4170 case Instruction::Mul:
4174 case Instruction::Shl:
4178 case Instruction::LShr:
4179 case Instruction::AShr:
4183 case Instruction::SRem:
4187 case Instruction::UDiv:
4191 case Instruction::SDiv:
4195 case Instruction::Sub:
4199 case Instruction::Add:
4223 if (!
II->hasOneUse())
4239 Value *Op0 =
II->getOperand(0);
4240 Value *Op1 =
II->getOperand(1);
4249 switch (
II->getIntrinsicID()) {
4252 "This function only works with usub_sat and uadd_sat for now!");
4253 case Intrinsic::uadd_sat:
4256 case Intrinsic::usub_sat:
4266 II->getBinaryOp(), *COp1,
II->getNoWrapKind());
4273 if (
II->getBinaryOp() == Instruction::Add)
4279 SatValCheck ? Instruction::BinaryOps::Or : Instruction::BinaryOps::And;
4281 std::optional<ConstantRange> Combination;
4282 if (CombiningOp == Instruction::BinaryOps::Or)
4283 Combination =
C1.exactUnionWith(C2);
4285 Combination =
C1.exactIntersectWith(C2);
4294 Combination->getEquivalentICmp(EquivPred, EquivInt, EquivOffset);
4298 Builder.CreateAdd(Op0, ConstantInt::get(Op1->
getType(), EquivOffset)),
4299 ConstantInt::get(Op1->
getType(), EquivInt));
4306 std::optional<ICmpInst::Predicate> NewPredicate = std::nullopt;
4311 NewPredicate = Pred;
4315 else if (
C.isAllOnes())
4323 else if (
C.isZero())
4340 if (!
C.isZero() && !
C.isAllOnes())
4351 if (
I->getIntrinsicID() == Intrinsic::scmp)
4365 switch (
II->getIntrinsicID()) {
4368 case Intrinsic::uadd_sat:
4369 case Intrinsic::usub_sat:
4374 case Intrinsic::ctpop: {
4379 case Intrinsic::scmp:
4380 case Intrinsic::ucmp:
4386 if (Cmp.isEquality())
4389 Type *Ty =
II->getType();
4391 switch (
II->getIntrinsicID()) {
4392 case Intrinsic::ctpop: {
4404 case Intrinsic::ctlz: {
4407 unsigned Num =
C.getLimitedValue();
4410 II->getArgOperand(0), ConstantInt::get(Ty, Limit));
4415 unsigned Num =
C.getLimitedValue();
4418 II->getArgOperand(0), ConstantInt::get(Ty, Limit));
4422 case Intrinsic::cttz: {
4424 if (!
II->hasOneUse())
4431 Builder.CreateAnd(
II->getArgOperand(0), Mask),
4439 Builder.CreateAnd(
II->getArgOperand(0), Mask),
4444 case Intrinsic::ssub_sat:
4451 return new ICmpInst(Pred,
II->getArgOperand(0),
II->getArgOperand(1));
4455 II->getArgOperand(1));
4459 II->getArgOperand(1));
4462 case Intrinsic::abs: {
4463 if (!
II->hasOneUse())
4472 Builder.CreateAdd(
X, ConstantInt::get(Ty,
C)),
4473 ConstantInt::get(Ty, 2 *
C));
4480 Builder.CreateAdd(
X, ConstantInt::get(Ty,
C - 1)),
4481 ConstantInt::get(Ty, 2 * (
C - 1)));
4494 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
4501 case Instruction::IntToPtr:
4506 APInt NullPtrValue =
4514 case Instruction::Load:
4531 auto SimplifyOp = [&](
Value *
Op,
bool SelectCondIsTrue) ->
Value * {
4535 SI->getCondition(), Pred,
Op, RHS,
DL, SelectCondIsTrue))
4536 return ConstantInt::get(
I.getType(), *Impl);
4541 Value *Op1 = SimplifyOp(
SI->getOperand(1),
true);
4545 Value *Op2 = SimplifyOp(
SI->getOperand(2),
false);
4549 auto Simplifies = [&](
Value *
Op,
unsigned Idx) {
4564 bool Transform =
false;
4567 else if (Simplifies(Op1, 1) || Simplifies(Op2, 2)) {
4569 if (
SI->hasOneUse())
4572 else if (CI && !CI->
isZero())
4580 Op1 =
Builder.CreateICmp(Pred,
SI->getOperand(1), RHS,
I.getName());
4582 Op2 =
Builder.CreateICmp(Pred,
SI->getOperand(2), RHS,
I.getName());
4600 if (C1SatisfiesCond && !C2SatisfiesCond) {
4604 Value *Cmp2 =
Builder.CreateICmp(Pred, RHS,
SI->getFalseValue());
4606 return BinaryOperator::CreateOr(Cmp1, Cmp2);
4607 return BinaryOperator::CreateAnd(Cmp1, Cmp2);
4617 unsigned Depth = 0) {
4620 if (V->getType()->getScalarSizeInBits() == 1)
4628 switch (
I->getOpcode()) {
4629 case Instruction::ZExt:
4632 case Instruction::SExt:
4636 case Instruction::And:
4637 case Instruction::Or:
4644 case Instruction::Xor:
4654 case Instruction::Select:
4658 case Instruction::Shl:
4661 case Instruction::LShr:
4664 case Instruction::AShr:
4668 case Instruction::Add:
4674 case Instruction::Sub:
4680 case Instruction::Call: {
4682 switch (
II->getIntrinsicID()) {
4685 case Intrinsic::umax:
4686 case Intrinsic::smax:
4687 case Intrinsic::umin:
4688 case Intrinsic::smin:
4693 case Intrinsic::bitreverse:
4783 auto IsLowBitMask = [&]() {
4801 auto Check = [&]() {
4819 auto Check = [&]() {
4838 if (!IsLowBitMask())
4874 const APInt &MaskedBits = *
C0;
4875 assert(MaskedBits != 0 &&
"shift by zero should be folded away already.");
4896 auto *XType =
X->getType();
4897 const unsigned XBitWidth = XType->getScalarSizeInBits();
4899 assert(
BitWidth.ugt(MaskedBits) &&
"shifts should leave some bits untouched");
4912 Value *T0 = Builder.CreateAdd(
X, ConstantInt::get(XType, AddCst));
4914 Value *
T1 = Builder.CreateICmp(DstPred, T0, ConstantInt::get(XType, ICmpCst));
4930 !
I.getOperand(0)->hasOneUse())
4955 assert(NarrowestTy ==
I.getOperand(0)->getType() &&
4956 "We did not look past any shifts while matching XShift though.");
4957 bool HadTrunc = WidestTy !=
I.getOperand(0)->getType();
4964 auto XShiftOpcode = XShift->
getOpcode();
4965 if (XShiftOpcode == YShift->
getOpcode())
4968 Value *
X, *XShAmt, *
Y, *YShAmt;
4977 if (!
match(
I.getOperand(0),
5003 unsigned MaximalPossibleTotalShiftAmount =
5006 APInt MaximalRepresentableShiftAmount =
5008 if (MaximalRepresentableShiftAmount.
ult(MaximalPossibleTotalShiftAmount))
5017 if (NewShAmt->getType() != WidestTy) {
5027 if (!
match(NewShAmt,
5029 APInt(WidestBitWidth, WidestBitWidth))))
5034 auto CanFold = [NewShAmt, WidestBitWidth, NarrowestShift, SQ,
5040 ? NewShAmt->getSplatValue()
5043 if (NewShAmtSplat &&
5051 unsigned MinLeadZero =
Known.countMinLeadingZeros();
5053 unsigned MaxActiveBits =
Known.getBitWidth() - MinLeadZero;
5054 if (MaxActiveBits <= 1)
5062 unsigned MinLeadZero =
Known.countMinLeadingZeros();
5064 unsigned MaxActiveBits =
Known.getBitWidth() - MinLeadZero;
5065 if (MaxActiveBits <= 1)
5068 if (NewShAmtSplat) {
5071 if (AdjNewShAmt.
ule(MinLeadZero))
5082 X = Builder.CreateZExt(
X, WidestTy);
5083 Y = Builder.CreateZExt(
Y, WidestTy);
5085 Value *T0 = XShiftOpcode == Instruction::BinaryOps::LShr
5086 ? Builder.CreateLShr(
X, NewShAmt)
5087 : Builder.CreateShl(
X, NewShAmt);
5088 Value *
T1 = Builder.CreateAnd(T0,
Y);
5089 return Builder.CreateICmp(
I.getPredicate(),
T1,
5107 if (!
I.isEquality() &&
5117 NeedNegation =
false;
5120 NeedNegation =
true;
5126 if (
I.isEquality() &&
5141 bool MulHadOtherUses =
Mul && !
Mul->hasOneUse();
5142 if (MulHadOtherUses)
5146 Div->
getOpcode() == Instruction::UDiv ? Intrinsic::umul_with_overflow
5147 : Intrinsic::smul_with_overflow,
5148 X->getType(), {X, Y},
nullptr,
"mul");
5153 if (MulHadOtherUses)
5158 Res =
Builder.CreateNot(Res,
"mul.not.ov");
5162 if (MulHadOtherUses)
5188 Type *Ty =
X->getType();
5192 Value *
And = Builder.CreateAnd(
X, MaxSignedVal);
5202 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5264 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5299 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1), *
A;
5315 return new ICmpInst(PredOut, Op0, Op1);
5335 return new ICmpInst(NewPred, Op0, Const);
5347 if (!
C.isPowerOf2())
5354 bool &HasNSW,
bool &HasNUW) {
5362 if (BO.
getOpcode() == Instruction::Or) {
5384 bool Op0HasNSW =
false, Op0HasNUW =
false;
5385 bool Op1HasNSW =
false, Op1HasNUW =
false;
5386 bool NoOp0WrapProblem =
hasNoWrapProblem(*BO0, Pred, Op0HasNSW, Op0HasNUW);
5387 bool NoOp1WrapProblem =
hasNoWrapProblem(*BO1, Pred, Op1HasNSW, Op1HasNUW);
5394 if (!NoOp0WrapProblem || !NoOp1WrapProblem)
5424 if (BO0->getOpcode() != BO1->getOpcode())
5427 A = BO0->getOperand(0);
5428 B = BO0->getOperand(1);
5429 C = BO1->getOperand(0);
5430 D = BO1->getOperand(1);
5432 switch (BO0->getOpcode()) {
5433 case Instruction::Sub:
5434 if (!NoOp0WrapProblem || !NoOp1WrapProblem)
5451 case Instruction::Mul: {
5454 if (IsEquality || !NoOp0WrapProblem || !NoOp1WrapProblem)
5464 }
else if (
A ==
D) {
5469 }
else if (
B ==
C) {
5474 }
else if (
B ==
D) {
5509 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5524 Value *Dividend, *Divisor;
5525 if (
I.isEquality() &&
5530 return new ICmpInst(NewPred, Dividend, Divisor);
5589 return new ICmpInst(NewPred, Op1, Zero);
5598 return new ICmpInst(NewPred, Op0, Zero);
5602 bool NoOp0WrapProblem =
false, NoOp1WrapProblem =
false;
5603 bool Op0HasNUW =
false, Op1HasNUW =
false;
5604 bool Op0HasNSW =
false, Op1HasNSW =
false;
5607 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr;
5620 if ((
A == Op1 ||
B == Op1) && NoOp0WrapProblem)
5626 if ((
C == Op0 ||
D == Op0) && NoOp1WrapProblem)
5634 return new ICmpInst(Pred, LHS, RHS);
5640 bool IsNegative) ->
bool {
5641 const APInt *OffsetC;
5653 if (!
C.isStrictlyPositive())
5680 if (
A && NoOp0WrapProblem && IsAddOrSignedPred &&
5681 ShareCommonDivisor(
A, Op1,
B, IsNegative))
5691 if (
C && NoOp1WrapProblem &&
5692 ShareCommonDivisor(Op0,
C,
D,
5705 if (
A &&
C && NoOp0WrapProblem && NoOp1WrapProblem &&
5707 const APInt *AP1, *AP2;
5715 if (AP1Abs.
uge(AP2Abs)) {
5716 APInt Diff = *AP1 - *AP2;
5719 A, C3,
"", Op0HasNUW && Diff.
ule(*AP1), Op0HasNSW);
5722 APInt Diff = *AP2 - *AP1;
5725 C, C3,
"", Op1HasNUW && Diff.
ule(*AP2), Op1HasNSW);
5744 if (BO0 && BO0->
getOpcode() == Instruction::Sub) {
5748 if (BO1 && BO1->
getOpcode() == Instruction::Sub) {
5754 if (
A == Op1 && NoOp0WrapProblem)
5757 if (
C == Op0 && NoOp1WrapProblem)
5781 if (RHSC->isNotMinSignedValue())
5782 return new ICmpInst(
I.getSwappedPredicate(),
X,
5800 if (Op0HasNSW && Op1HasNSW) {
5802 SQ.getWithInstruction(&
I));
5807 SQ.getWithInstruction(&
I));
5808 if (GreaterThan &&
match(GreaterThan,
m_One()))
5814 if (((Op0HasNSW && Op1HasNSW) || (Op0HasNUW && Op1HasNUW)) &&
5826 if (NonZero && Op0HasNSW && Op1HasNSW)
5831 if (NonZero && Op0HasNUW && Op1HasNUW)
5842 else if (BO1 && BO1->
getOpcode() == Instruction::SRem &&
5872 case Instruction::Add:
5873 case Instruction::Sub:
5874 case Instruction::Xor: {
5881 if (
C->isSignMask()) {
5887 if (BO0->
getOpcode() == Instruction::Xor &&
C->isMaxSignedValue()) {
5889 NewPred =
I.getSwappedPredicate(NewPred);
5895 case Instruction::Mul: {
5896 if (!
I.isEquality())
5904 if (
unsigned TZs =
C->countr_zero()) {
5910 return new ICmpInst(Pred, And1, And2);
5915 case Instruction::UDiv:
5916 case Instruction::LShr:
5921 case Instruction::SDiv:
5927 case Instruction::AShr:
5932 case Instruction::Shl: {
5933 bool NUW = Op0HasNUW && Op1HasNUW;
5934 bool NSW = Op0HasNSW && Op1HasNSW;
5937 if (!NSW &&
I.isSigned())
6001 auto IsCondKnownTrue = [](
Value *Val) -> std::optional<bool> {
6003 return std::nullopt;
6008 return std::nullopt;
6014 Pred = Pred.dropSameSign();
6017 if (!CmpXZ.has_value() && !CmpYZ.has_value())
6019 if (!CmpXZ.has_value()) {
6025 if (CmpYZ.has_value())
6049 if (!MinMaxCmpXZ.has_value()) {
6057 if (!MinMaxCmpXZ.has_value())
6073 return FoldIntoCmpYZ();
6100 return FoldIntoCmpYZ();
6109 return FoldIntoCmpYZ();
6141 const APInt *
Lo =
nullptr, *
Hi =
nullptr;
6164 I,
Builder.CreateICmp(Pred,
X, ConstantInt::get(
X->getType(),
C)));
6170 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6174 if (
I.isEquality()) {
6209 Type *Ty =
A->getType();
6210 Value *CtPop = Builder.CreateUnaryIntrinsic(Intrinsic::ctpop,
A);
6212 ConstantInt::get(Ty, 2))
6214 ConstantInt::get(Ty, 1));
6221using OffsetOp = std::pair<Instruction::BinaryOps, Value *>;
6223 bool AllowRecursion) {
6229 case Instruction::Add:
6230 Offsets.emplace_back(Instruction::Sub, Inst->
getOperand(1));
6231 Offsets.emplace_back(Instruction::Sub, Inst->
getOperand(0));
6233 case Instruction::Sub:
6234 Offsets.emplace_back(Instruction::Add, Inst->
getOperand(1));
6236 case Instruction::Xor:
6237 Offsets.emplace_back(Instruction::Xor, Inst->
getOperand(1));
6238 Offsets.emplace_back(Instruction::Xor, Inst->
getOperand(0));
6240 case Instruction::Shl:
6242 Offsets.emplace_back(Instruction::AShr, Inst->
getOperand(1));
6244 Offsets.emplace_back(Instruction::LShr, Inst->
getOperand(1));
6246 case Instruction::Select:
6247 if (AllowRecursion) {
6294 assert(
I.isEquality() &&
"Expected an equality icmp");
6295 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6306 case Instruction::AShr: {
6307 const APInt *CV, *CRHS;
6309 CV->
ashr(*CRHS).
shl(*CRHS) == *CV) &&
6315 case Instruction::LShr: {
6316 const APInt *CV, *CRHS;
6318 CV->
lshr(*CRHS).
shl(*CRHS) == *CV) &&
6337 auto ApplyOffset = [&](
Value *V,
unsigned BinOpc,
6340 if (!Sel->hasOneUse())
6342 Value *TrueVal = ApplyOffsetImpl(Sel->getTrueValue(), BinOpc,
RHS);
6345 Value *FalseVal = ApplyOffsetImpl(Sel->getFalseValue(), BinOpc,
RHS);
6350 if (
Value *Simplified = ApplyOffsetImpl(V, BinOpc,
RHS))
6355 for (
auto [BinOp,
RHS] : OffsetOps) {
6356 auto BinOpc =
static_cast<unsigned>(BinOp);
6358 auto Op0Result = ApplyOffset(Op0, BinOpc,
RHS);
6359 if (!Op0Result.isValid())
6361 auto Op1Result = ApplyOffset(Op1, BinOpc,
RHS);
6362 if (!Op1Result.isValid())
6365 Value *NewLHS = Op0Result.materialize(Builder);
6366 Value *NewRHS = Op1Result.materialize(Builder);
6367 return new ICmpInst(
I.getPredicate(), NewLHS, NewRHS);
6374 if (!
I.isEquality())
6377 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
6381 if (
A == Op1 ||
B == Op1) {
6382 Value *OtherVal =
A == Op1 ?
B :
A;
6410 Value *OtherVal =
A == Op0 ?
B :
A;
6417 Value *
X =
nullptr, *
Y =
nullptr, *Z =
nullptr;
6423 }
else if (
A ==
D) {
6427 }
else if (
B ==
C) {
6431 }
else if (
B ==
D) {
6443 (*
C0 ^ *
C1).isNegatedPowerOf2();
6449 int(Op0->
hasOneUse()) + int(Op1->hasOneUse()) +
6451 if (XorIsNegP2 || UseCnt >= 2) {
6454 Op1 =
Builder.CreateAnd(Op1, Z);
6474 (Op0->
hasOneUse() || Op1->hasOneUse())) {
6479 MaskC->
countr_one() ==
A->getType()->getScalarSizeInBits())
6485 const APInt *AP1, *AP2;
6494 if (ShAmt < TypeBits && ShAmt != 0) {
6499 return new ICmpInst(NewPred,
Xor, ConstantInt::get(
A->getType(), CmpVal));
6509 if (ShAmt < TypeBits && ShAmt != 0) {
6529 if (ShAmt < ASize) {
6552 A->getType()->getScalarSizeInBits() ==
BitWidth * 2 &&
6553 (
I.getOperand(0)->hasOneUse() ||
I.getOperand(1)->hasOneUse())) {
6558 Add, ConstantInt::get(
A->getType(),
C.shl(1)));
6585 Builder.CreateIntrinsic(Op0->
getType(), Intrinsic::fshl, {A, A, B}));
6600 std::optional<bool> IsZero = std::nullopt;
6642 Constant *
C = ConstantInt::get(Res->X->getType(), Res->C);
6646 unsigned SrcBits =
X->getType()->getScalarSizeInBits();
6648 if (
II->getIntrinsicID() == Intrinsic::cttz ||
6649 II->getIntrinsicID() == Intrinsic::ctlz) {
6650 unsigned MaxRet = SrcBits;
6676 bool IsSignedExt = CastOp0->getOpcode() == Instruction::SExt;
6677 bool IsSignedCmp = ICmp.
isSigned();
6685 if (IsZext0 != IsZext1) {
6690 if (ICmp.
isEquality() &&
X->getType()->isIntOrIntVectorTy(1) &&
6691 Y->getType()->isIntOrIntVectorTy(1))
6701 bool IsNonNeg0 = NonNegInst0 && NonNegInst0->hasNonNeg();
6702 bool IsNonNeg1 = NonNegInst1 && NonNegInst1->hasNonNeg();
6704 if ((IsZext0 && IsNonNeg0) || (IsZext1 && IsNonNeg1))
6711 Type *XTy =
X->getType(), *YTy =
Y->getType();
6718 IsSignedExt ? Instruction::SExt : Instruction::ZExt;
6720 X =
Builder.CreateCast(CastOpcode,
X, YTy);
6722 Y =
Builder.CreateCast(CastOpcode,
Y, XTy);
6734 if (IsSignedCmp && IsSignedExt)
6747 Type *SrcTy = CastOp0->getSrcTy();
6755 if (IsSignedExt && IsSignedCmp)
6786 Value *SimplifiedOp0 = simplifyIntToPtrRoundTripCast(ICmp.
getOperand(0));
6787 Value *SimplifiedOp1 = simplifyIntToPtrRoundTripCast(ICmp.
getOperand(1));
6788 if (SimplifiedOp0 || SimplifiedOp1)
6790 SimplifiedOp0 ? SimplifiedOp0 : ICmp.
getOperand(0),
6791 SimplifiedOp1 ? SimplifiedOp1 : ICmp.
getOperand(1));
6800 Value *Op0Src = CastOp0->getOperand(0);
6801 Type *SrcTy = CastOp0->getSrcTy();
6802 Type *DestTy = CastOp0->getDestTy();
6806 auto CompatibleSizes = [&](
Type *PtrTy,
Type *IntTy) {
6807 unsigned IntWidth = IntTy->getScalarType()->getIntegerBitWidth();
6808 unsigned IndexWidth =
DL.getAddressSizeInBits(PtrTy);
6809 unsigned PtrWidth =
DL.getPointerTypeSizeInBits(PtrTy);
6812 return IntWidth == IndexWidth && IndexWidth == PtrWidth;
6816 Value *NewOp1 =
nullptr;
6818 NewOp1 = PtrToIntOp1->getOperand(0);
6821 NewOp1 = PtrToAddrOp1->getOperand(0);
6828 if ((!HasPtrToInt || CompatibleSizes(SrcTy, DestTy)) &&
6834 if (CastOp0->getOpcode() == Instruction::IntToPtr &&
6835 CompatibleSizes(DestTy, SrcTy)) {
6836 Value *NewOp1 =
nullptr;
6838 Value *IntSrc = IntToPtrOp1->getOperand(0);
6840 NewOp1 = IntToPtrOp1->getOperand(0);
6860 case Instruction::Add:
6861 case Instruction::Sub:
6863 case Instruction::Mul:
6864 return !(
RHS->getType()->isIntOrIntVectorTy(1) && IsSigned) &&
6876 case Instruction::Add:
6881 case Instruction::Sub:
6886 case Instruction::Mul:
6895 bool IsSigned,
Value *LHS,
6906 Builder.SetInsertPoint(&OrigI);
6923 Result = Builder.CreateBinOp(BinaryOp,
LHS,
RHS);
6924 Result->takeName(&OrigI);
6928 Result = Builder.CreateBinOp(BinaryOp,
LHS,
RHS);
6929 Result->takeName(&OrigI);
6933 Inst->setHasNoSignedWrap();
6935 Inst->setHasNoUnsignedWrap();
6960 const APInt *OtherVal,
6968 unsigned Opcode = Instr->getOpcode();
6969 assert(Opcode == Instruction::Add || Opcode == Instruction::Mul);
6976 Type *TyA =
A->getType(), *TyB =
B->getType();
6978 WidthB = TyB->getPrimitiveSizeInBits();
6979 unsigned ResultWidth;
6981 if (WidthB > WidthA) {
6982 ResultWidth = WidthB;
6985 ResultWidth = WidthA;
6998 unsigned TruncWidth = TI->getType()->getPrimitiveSizeInBits();
6999 if (TruncWidth > ResultWidth)
7003 if (BO->getOpcode() != Instruction::And)
7006 const APInt &CVal = CI->getValue();
7022 switch (
I.getPredicate()) {
7029 if (MaxVal.
eq(*OtherVal))
7039 if (MaxVal.
eq(*OtherVal))
7052 Value *ResultA =
A, *ResultB =
B;
7053 if (WidthA < ResultWidth)
7054 ResultA = Builder.CreateZExt(
A, ResultType);
7055 if (WidthB < ResultWidth)
7056 ResultB = Builder.CreateZExt(
B, ResultType);
7059 Value *OverflowCheck;
7061 if (Opcode == Instruction::Add) {
7063 ArithResult = Builder.CreateAdd(ResultA, ResultB,
"add");
7067 Builder.CreateICmpUGE(ArithResult, ResultA,
"not.add.overflow");
7070 Builder.CreateICmpULT(ArithResult, ResultA,
"add.overflow");
7073 Value *
Call = Builder.CreateIntrinsic(Intrinsic::umul_with_overflow,
7074 ResultType, {ResultA, ResultB},
7076 ArithResult = Builder.CreateExtractValue(
Call, 0,
"umul.value");
7077 OverflowCheck = Builder.CreateExtractValue(
Call, 1,
"umul.overflow");
7079 OverflowCheck = Builder.CreateNot(OverflowCheck);
7090 if (TI->getType()->getPrimitiveSizeInBits() == ResultWidth)
7095 assert(BO->getOpcode() == Instruction::And);
7099 Value *ShortAnd = Builder.CreateAnd(ArithResult, ShortMask);
7100 Value *Zext = Builder.CreateZExt(ShortAnd, BO->
getType());
7126 switch (
I.getPredicate()) {
7157 assert(DI && UI &&
"Instruction not defined\n");
7169 if (Usr != UI && !
DT.dominates(DB, Usr->getParent()))
7184 if (!IC || (IC->getOperand(0) !=
SI && IC->getOperand(1) !=
SI))
7231 const unsigned SIOpd) {
7232 assert((SIOpd == 1 || SIOpd == 2) &&
"Invalid select operand!");
7234 BasicBlock *Succ =
SI->getParent()->getTerminator()->getSuccessor(1);
7248 SI->replaceUsesOutsideBlock(
SI->getOperand(SIOpd),
SI->getParent());
7258 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7263 unsigned BitWidth = Ty->isIntOrIntVectorTy()
7264 ? Ty->getScalarSizeInBits()
7265 :
DL.getPointerTypeSizeInBits(Ty->getScalarType());
7289 if (
I.hasSameSign() &&
I.isUnsigned()) {
7291 if (To.isNegative() || To.isNonNegative())
7296 To.makeNonNegative();
7298 PropagateSignBit(Op0Known, Op1Known);
7299 PropagateSignBit(Op1Known, Op0Known);
7334 if (!Cmp.hasOneUse())
7343 if (!isMinMaxCmp(
I)) {
7348 if (Op1Min == Op0Max)
7353 if (*CmpC == Op0Min + 1)
7355 ConstantInt::get(Op1->getType(), *CmpC - 1));
7365 if (Op1Max == Op0Min)
7370 if (*CmpC == Op0Max - 1)
7372 ConstantInt::get(Op1->getType(), *CmpC + 1));
7382 if (Op1Min == Op0Max)
7386 if (*CmpC == Op0Min + 1)
7388 ConstantInt::get(Op1->getType(), *CmpC - 1));
7393 if (Op1Max == Op0Min)
7397 if (*CmpC == Op0Max - 1)
7399 ConstantInt::get(Op1->getType(), *CmpC + 1));
7416 APInt Op0KnownZeroInverted = ~Op0Known.Zero;
7419 Value *LHS =
nullptr;
7422 *LHSC != Op0KnownZeroInverted)
7428 Type *XTy =
X->getType();
7429 unsigned Log2C1 =
C1->countr_zero();
7430 APInt C2 = Op0KnownZeroInverted;
7437 auto *CmpC = ConstantInt::get(XTy, Log2C2 - Log2C1);
7447 (Op0Known & Op1Known) == Op0Known)
7453 if (Op1Min == Op0Max)
7457 if (Op1Max == Op0Min)
7461 if (Op1Min == Op0Max)
7465 if (Op1Max == Op0Min)
7473 if ((
I.isSigned() || (
I.isUnsigned() && !
I.hasSameSign())) &&
7476 I.setPredicate(
I.getUnsignedPredicate());
7494 return BinaryOperator::CreateAnd(
Builder.CreateIsNull(
X),
Y);
7500 return BinaryOperator::CreateOr(
Builder.CreateIsNull(
X),
Y);
7511 bool IsSExt = ExtI->
getOpcode() == Instruction::SExt;
7513 auto CreateRangeCheck = [&] {
7528 }
else if (!IsSExt || HasOneUse) {
7533 return CreateRangeCheck();
7535 }
else if (IsSExt ?
C->isAllOnes() :
C->isOne()) {
7543 }
else if (!IsSExt || HasOneUse) {
7548 return CreateRangeCheck();
7562 Instruction::ICmp, Pred1,
X,
7581 Value *Op0 =
I.getOperand(0);
7582 Value *Op1 =
I.getOperand(1);
7588 if (!FlippedStrictness)
7592 new ICmpInst(FlippedStrictness->first, Op0, FlippedStrictness->second);
7593 NewCmp->setSameSign(FlippedStrictness->first.hasSameSign());
7612 I.setName(
I.getName() +
".not");
7623 Value *
A =
I.getOperand(0), *
B =
I.getOperand(1);
7624 assert(
A->getType()->isIntOrIntVectorTy(1) &&
"Bools only");
7630 switch (
I.getPredicate()) {
7639 switch (
I.getPredicate()) {
7649 switch (
I.getPredicate()) {
7658 return BinaryOperator::CreateXor(
A,
B);
7666 return BinaryOperator::CreateAnd(Builder.CreateNot(
A),
B);
7674 return BinaryOperator::CreateAnd(Builder.CreateNot(
B),
A);
7682 return BinaryOperator::CreateOr(Builder.CreateNot(
A),
B);
7690 return BinaryOperator::CreateOr(Builder.CreateNot(
B),
A);
7738 Value *NewX = Builder.CreateLShr(
X,
Y,
X->getName() +
".highbits");
7746 Value *
LHS = Cmp.getOperand(0), *
RHS = Cmp.getOperand(1);
7750 Value *V = Builder.CreateCmp(Pred,
X,
Y, Cmp.getName());
7752 I->copyIRFlags(&Cmp);
7753 Module *M = Cmp.getModule();
7755 M, Intrinsic::vector_reverse, V->getType());
7762 (
LHS->hasOneUse() ||
RHS->hasOneUse()))
7763 return createCmpReverse(Pred,
V1, V2);
7767 return createCmpReverse(Pred,
V1,
RHS);
7771 return createCmpReverse(Pred,
LHS, V2);
7780 Type *V1Ty =
V1->getType();
7782 V1Ty == V2->
getType() && (
LHS->hasOneUse() ||
RHS->hasOneUse())) {
7783 Value *NewCmp = Builder.CreateCmp(Pred,
V1, V2);
7796 Constant *ScalarC =
C->getSplatValue(
true);
7804 Value *NewCmp = Builder.CreateCmp(Pred,
V1,
C);
7815 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
7821 if (
match(Op0, UAddOvResultPat) &&
7832 (Op0 ==
A || Op0 ==
B))
7842 if (!
I.getOperand(0)->getType()->isPointerTy() ||
7844 I.getParent()->getParent(),
7845 I.getOperand(0)->getType()->getPointerAddressSpace())) {
7849 if (
match(
I.getOperand(0),
7865 Value *Const =
I.getOperand(1);
7883 Type *VecEltTy = VecTy->getElementType();
7885 DL.getTypeSizeInBits(VecEltTy) * VecTy->getNumElements();
7886 if (!
DL.fitsInLegalInteger(ScalarBW))
7890 ? ConstantInt::get(ScalarTy, 0)
7893 Builder.CreateBitCast(Vec, ScalarTy), NewConst);
7905 if (
I.getType()->isVectorTy())
7928 if (!LHSTy || !LHSTy->getElementType()->isIntegerTy())
7931 LHSTy->getNumElements() * LHSTy->getElementType()->getIntegerBitWidth();
7933 if (!
DL.isLegalInteger(NumBits))
7937 auto *ScalarTy = Builder.getIntNTy(NumBits);
7938 LHS = Builder.CreateBitCast(
LHS, ScalarTy,
LHS->getName() +
".scalar");
7939 RHS = Builder.CreateBitCast(
RHS, ScalarTy,
RHS->getName() +
".scalar");
7995 bool IsIntMinPosion =
C->isAllOnesValue();
8007 CtxI, IsIntMinPosion
8008 ?
Builder.CreateICmpSGT(
X, AllOnesValue)
8010 X, ConstantInt::get(
X->getType(),
SMin + 1)));
8016 CtxI, IsIntMinPosion
8017 ?
Builder.CreateICmpSLT(
X, NullValue)
8019 X, ConstantInt::get(
X->getType(),
SMin)));
8046 auto CheckUGT1 = [](
const APInt &Divisor) {
return Divisor.ugt(1); };
8061 auto CheckNE0 = [](
const APInt &Shift) {
return !Shift.isZero(); };
8082 if (ShAmt >=
X->getType()->getScalarSizeInBits())
8084 if (canEvaluateShifted(Op1, ShAmt,
false,
8086 Value *NewOp1 = getShiftedValue(Op1, ShAmt,
false,
8094 if (ShAmt >=
X->getType()->getScalarSizeInBits())
8096 if (canEvaluateShifted(Op1, ShAmt,
false,
8098 Value *NewOp1 = getShiftedValue(Op1, ShAmt,
false,
8109 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
8116 if (Op0Cplxity < Op1Cplxity) {
8179 if (
C->isNonNegative())
8183 ConstantInt::get(
X->getType(), ~*
C));
8189 if (
C->isNonNegative())
8193 ConstantInt::get(
X->getType(), ~*
C));
8249 if (
I.isCommutative()) {
8250 if (
auto Pair = matchSymmetricPair(
I.getOperand(0),
I.getOperand(1))) {
8279 (Op0->
hasOneUse() || Op1->hasOneUse())) {
8307 bool I0NUW = I0->hasNoUnsignedWrap();
8308 bool I1NUW = I1->hasNoUnsignedWrap();
8309 bool I0NSW = I0->hasNoSignedWrap();
8310 bool I1NSW = I1->hasNoSignedWrap();
8314 ((I0NUW || I0NSW) && (I1NUW || I1NSW)))) {
8316 ConstantInt::get(Op0->
getType(), 0));
8323 assert(Op1->getType()->isPointerTy() &&
8324 "Comparing pointer with non-pointer?");
8348 Type *SmallType =
X->getType();
8350 if (Mask->isMask(SmallWidth) &&
8351 shouldChangeType(
I.getOperand(0)->getType(), SmallType)) {
8353 return new ICmpInst(
I.getUnsignedPredicate(), NewTrunc,
X);
8371 bool ConsumesOp0, ConsumesOp1;
8374 (ConsumesOp0 || ConsumesOp1)) {
8377 assert(InvOp0 && InvOp1 &&
8378 "Mismatch between isFreeToInvert and getFreelyInverted");
8379 return new ICmpInst(
I.getSwappedPredicate(), InvOp0, InvOp1);
8391 if (AddI->
getOpcode() == Instruction::Add &&
8392 OptimizeOverflowCheck(Instruction::Add,
false,
X,
Y, *AddI,
8393 Result, Overflow)) {
8413 if ((
I.isUnsigned() ||
I.isEquality()) &&
8416 Y->getType()->getScalarSizeInBits() == 1 &&
8417 (Op0->
hasOneUse() || Op1->hasOneUse())) {
8424 unsigned ShiftOpc = ShiftI->
getOpcode();
8425 if ((ExtOpc == Instruction::ZExt && ShiftOpc == Instruction::LShr) ||
8426 (ExtOpc == Instruction::SExt && ShiftOpc == Instruction::AShr)) {
8460 if (EVI->getIndices()[0] == 0 && ACXI->getCompareOperand() == Op1 &&
8467 if (
I.getType()->isVectorTy())
8486 Type *InputTy =
A->getType();
8490 APInt TruncC1 =
C1->trunc(InputBitWidth);
8493 TruncC1.
setBit(InputBitWidth - 1);
8497 ConstantInt::get(InputTy, C2->
trunc(InputBitWidth)));
8517 if (MantissaWidth == -1)
8524 if (
I.isEquality()) {
8526 bool IsExact =
false;
8527 APSInt RHSCvt(IntWidth, LHSUnsigned);
8536 if (*RHS != RHSRoundInt) {
8556 if ((
int)IntWidth > MantissaWidth) {
8558 int Exp =
ilogb(*RHS);
8561 if (MaxExponent < (
int)IntWidth - !LHSUnsigned)
8567 if (MantissaWidth <= Exp && Exp <= (
int)IntWidth - !LHSUnsigned)
8576 assert(!RHS->isNaN() &&
"NaN comparison not already folded!");
8579 switch (
I.getPredicate()) {
8670 APSInt RHSInt(IntWidth, LHSUnsigned);
8673 if (!RHS->isZero()) {
8688 if (RHS->isNegative())
8694 if (RHS->isNegative())
8700 if (RHS->isNegative())
8707 if (!RHS->isNegative())
8713 if (RHS->isNegative())
8719 if (RHS->isNegative())
8725 if (RHS->isNegative())
8732 if (!RHS->isNegative())
8751 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
8759 if (
I.getType() !=
C1->getType() ||
I.getType() != C2->
getType())
8762 unsigned Pred =
I.getPredicate();
8770 if (!Res00 || !Res01 || !Res10 || !Res11)
8779 std::bitset<4>
Table;
8837 if (
C->isNegative())
8838 Pred =
I.getSwappedPredicate();
8865 "X ord/uno NaN should be folded away by simplifyFCmpInst()");
8871 bool RoundDown =
false;
8892 auto NextValue = [](
const APFloat &
Value,
bool RoundDown) {
8894 NextValue.
next(RoundDown);
8898 APFloat NextCValue = NextValue(*CValue, RoundDown);
8903 APFloat ExtCValue = ConvertFltSema(*CValue, DestFltSema);
8904 APFloat ExtNextCValue = ConvertFltSema(NextCValue, DestFltSema);
8911 APFloat PrevCValue = NextValue(*CValue, !RoundDown);
8912 APFloat Bias = ConvertFltSema(*CValue - PrevCValue, DestFltSema);
8914 ExtNextCValue = ExtCValue + Bias;
8921 C.getType()->getScalarType()->getFltSemantics();
8924 APFloat MidValue = ConvertFltSema(ExtMidValue, SrcFltSema);
8925 if (MidValue != *CValue)
8926 ExtMidValue.
next(!RoundDown);
8934 if (ConvertFltSema(ExtMidValue, SrcFltSema).isInfinity())
8938 APFloat NextExtMidValue = NextValue(ExtMidValue, RoundDown);
8939 if (ConvertFltSema(NextExtMidValue, SrcFltSema).
isFinite())
8944 ConstantFP::get(DestType, ExtMidValue),
"", &
I);
8957 if (!
C->isPosZero()) {
8958 if (!
C->isSmallestNormalized())
8971 switch (
I.getPredicate()) {
8997 switch (
I.getPredicate()) {
9022 assert(!
I.hasNoNaNs() &&
"fcmp should have simplified");
9027 assert(!
I.hasNoNaNs() &&
"fcmp should have simplified");
9041 return replacePredAndOp0(&
I,
I.getPredicate(),
X);
9064 I.setHasNoInfs(
false);
9066 switch (
I.getPredicate()) {
9111 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
9116 Pred =
I.getSwappedPredicate();
9125 return new FCmpInst(Pred, Op0, Zero,
"", &
I);
9161 I.getFunction()->getDenormalMode(
9168 I.setHasNoNaNs(
true);
9193 if (MantissaWidth != -1 &&
ilogb(*
C) < MantissaWidth) {
9195 I.setPredicate(
I.getSwappedPredicate());
9232 if (!IsStrictLt && !IsStrictGt && !IsGe)
9254 }
else if (
match(FAbsArg,
9262 if (
A->getType() !=
B->getType())
9277 Type *OpType =
LHS->getType();
9283 if (!FloorX && !CeilX) {
9287 Pred =
I.getSwappedPredicate();
9363 if (!
I || !(
I->getOpcode() == Instruction::SIToFP ||
9364 I->getOpcode() == Instruction::UIToFP))
9367 bool IsUnsigned =
I->getOpcode() == Instruction::UIToFP;
9368 unsigned BitWidth =
I->getOperand(0)->getType()->getScalarSizeInBits();
9391 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
9393 SQ.getWithInstruction(&
I)))
9398 assert(OpType == Op1->getType() &&
"fcmp with different-typed operands?");
9423 if (
I.isCommutative()) {
9424 if (
auto Pair = matchSymmetricPair(
I.getOperand(0),
I.getOperand(1))) {
9446 return new FCmpInst(
I.getSwappedPredicate(),
X,
Y,
"", &
I);
9462 bool IsRedundantMinMaxClamp =
9524 X->getType()->isIntOrIntVectorTy() &&
9525 !
F.getDenormalMode(Op1->getType()->getScalarType()->getFltSemantics())
9526 .inputsMayBeZero()) {
9534 Type *IntTy =
X->getType();
9535 const APInt &SignMask =
~APInt::getSignMask(IntTy->getScalarSizeInBits());
9536 Value *MaskX =
Builder.CreateAnd(
X, ConstantInt::get(IntTy, SignMask));
9546 case Instruction::Select:
9554 case Instruction::FSub:
9559 case Instruction::PHI:
9563 case Instruction::SIToFP:
9564 case Instruction::UIToFP:
9568 case Instruction::FDiv:
9572 case Instruction::Load:
9578 case Instruction::FPTrunc:
9605 return new FCmpInst(
I.getSwappedPredicate(),
X, NegC,
"", &
I);
9619 X->getType() ==
Y->getType())
9630 X->getType()->getScalarType()->getFltSemantics();
9666 Constant *NewC = ConstantFP::get(
X->getType(), TruncC);
9679 Type *IntType =
Builder.getIntNTy(
X->getType()->getScalarSizeInBits());
9692 Value *CanonLHS =
nullptr;
9695 if (CanonLHS == Op1)
9696 return new FCmpInst(Pred, Op1, Op1,
"", &
I);
9698 Value *CanonRHS =
nullptr;
9701 if (CanonRHS == Op0)
9702 return new FCmpInst(Pred, Op0, Op0,
"", &
I);
9705 if (CanonLHS && CanonRHS)
9706 return new FCmpInst(Pred, CanonLHS, CanonRHS,
"", &
I);
9709 if (
I.getType()->isVectorTy())
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static Instruction * foldFCmpReciprocalAndZero(FCmpInst &I, Instruction *LHSI, Constant *RHSC)
Fold (C / X) < 0.0 --> X < 0.0 if possible. Swap predicate if necessary.
static Instruction * foldFabsWithFcmpZero(FCmpInst &I, InstCombinerImpl &IC)
Optimize fabs(X) compared with zero.
static void collectOffsetOp(Value *V, SmallVectorImpl< OffsetOp > &Offsets, bool AllowRecursion)
static Value * rewriteGEPAsOffset(Value *Start, Value *Base, GEPNoWrapFlags NW, const DataLayout &DL, SetVector< Value * > &Explored, InstCombiner &IC)
Returns a re-written value of Start as an indexed GEP using Base as a pointer.
static bool isMinMaxCmpSelectEliminable(SelectPatternFlavor Flavor, Value *A, Value *B)
Returns true if a select that implements a min/max is redundant and select result can be replaced wit...
static Instruction * foldICmpEqualityWithOffset(ICmpInst &I, InstCombiner::BuilderTy &Builder, const SimplifyQuery &SQ)
Offset both sides of an equality icmp to see if we can save some instructions: icmp eq/ne X,...
static bool addWithOverflow(APInt &Result, const APInt &In1, const APInt &In2, bool IsSigned=false)
Compute Result = In1+In2, returning true if the result overflowed for this type.
static Instruction * foldICmpOfVectorReduce(ICmpInst &I, const DataLayout &DL, IRBuilderBase &Builder)
static Instruction * foldICmpAndXX(ICmpInst &I, const SimplifyQuery &Q, InstCombinerImpl &IC)
static Instruction * foldVectorCmp(CmpInst &Cmp, InstCombiner::BuilderTy &Builder)
static bool isMaskOrZero(const Value *V, bool Not, const SimplifyQuery &Q, unsigned Depth=0)
static Value * createLogicFromTable(const std::bitset< 4 > &Table, Value *Op0, Value *Op1, IRBuilderBase &Builder, bool HasOneUse)
static Instruction * foldICmpOfUAddOv(ICmpInst &I)
static bool isChainSelectCmpBranch(const SelectInst *SI)
Return true when the instruction sequence within a block is select-cmp-br.
static Instruction * foldICmpInvariantGroup(ICmpInst &I)
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
static Instruction * foldReductionIdiom(ICmpInst &I, InstCombiner::BuilderTy &Builder, const DataLayout &DL)
This function folds patterns produced by lowering of reduce idioms, such as llvm.vector....
static Instruction * canonicalizeICmpBool(ICmpInst &I, InstCombiner::BuilderTy &Builder)
Integer compare with boolean values can always be turned into bitwise ops.
static Instruction * foldFCmpFSubIntoFCmp(FCmpInst &I, Instruction *LHSI, Constant *RHSC, InstCombinerImpl &CI)
static Value * foldICmpOrXorSubChain(ICmpInst &Cmp, BinaryOperator *Or, InstCombiner::BuilderTy &Builder)
Fold icmp eq/ne (or (xor/sub (X1, X2), xor/sub (X3, X4))), 0.
static bool hasBranchUse(ICmpInst &I)
Given an icmp instruction, return true if any use of this comparison is a branch on sign bit comparis...
static Value * foldICmpWithLowBitMaskedVal(CmpPredicate Pred, Value *Op0, Value *Op1, const SimplifyQuery &Q, InstCombiner &IC)
Some comparisons can be simplified.
static APInt getDemandedBitsLHSMask(ICmpInst &I, unsigned BitWidth)
When performing a comparison against a constant, it is possible that not all the bits in the LHS are ...
static Instruction * foldICmpShlLHSC(ICmpInst &Cmp, Instruction *Shl, const APInt &C)
Fold icmp (shl nuw C2, Y), C.
static Instruction * foldFCmpWithFloorAndCeil(FCmpInst &I, InstCombinerImpl &IC)
static Instruction * foldICmpXorXX(ICmpInst &I, const SimplifyQuery &Q, InstCombinerImpl &IC)
static Instruction * processUZExtIdiom(ICmpInst &I, Value *Val, const APInt *OtherVal, InstCombinerImpl &IC)
Recognize and process idiom involving test for unsigned overflow.
static Instruction * foldICmpOfCmpIntrinsicWithConstant(CmpPredicate Pred, IntrinsicInst *I, const APInt &C, InstCombiner::BuilderTy &Builder)
static Instruction * foldSqrtWithFcmpZero(FCmpInst &I, InstCombinerImpl &IC)
Optimize sqrt(X) compared with zero.
static Instruction * foldFCmpFNegCommonOp(FCmpInst &I)
static bool hasNoWrapProblem(const BinaryOperator &BO, CmpInst::Predicate Pred, bool &HasNSW, bool &HasNUW)
static Instruction * foldICmpWithHighBitMask(ICmpInst &Cmp, InstCombiner::BuilderTy &Builder)
static ICmpInst * canonicalizeCmpWithConstant(ICmpInst &I)
If we have an icmp le or icmp ge instruction with a constant operand, turn it into the appropriate ic...
static Instruction * foldICmpIntrinsicWithIntrinsic(ICmpInst &Cmp, InstCombiner::BuilderTy &Builder)
Fold an icmp with LLVM intrinsics.
static Instruction * foldICmpUSubSatOrUAddSatWithConstant(CmpPredicate Pred, SaturatingInst *II, const APInt &C, InstCombiner::BuilderTy &Builder)
static Instruction * foldICmpPow2Test(ICmpInst &I, InstCombiner::BuilderTy &Builder)
static bool subWithOverflow(APInt &Result, const APInt &In1, const APInt &In2, bool IsSigned=false)
Compute Result = In1-In2, returning true if the result overflowed for this type.
static bool canRewriteGEPAsOffset(Value *Start, Value *Base, GEPNoWrapFlags &NW, const DataLayout &DL, SetVector< Value * > &Explored)
Returns true if we can rewrite Start as a GEP with pointer Base and some integer offset.
static Instruction * foldFCmpFpTrunc(FCmpInst &I, const Instruction &FPTrunc, const Constant &C)
static Instruction * foldICmpXNegX(ICmpInst &I, InstCombiner::BuilderTy &Builder)
static Instruction * processUGT_ADDCST_ADD(ICmpInst &I, Value *A, Value *B, ConstantInt *CI2, ConstantInt *CI1, InstCombinerImpl &IC)
The caller has matched a pattern of the form: I = icmp ugt (add (add A, B), CI2), CI1 If this is of t...
static Value * foldShiftIntoShiftInAnotherHandOfAndInICmp(ICmpInst &I, const SimplifyQuery SQ, InstCombiner::BuilderTy &Builder)
static bool isSignTest(ICmpInst::Predicate &Pred, const APInt &C)
Returns true if the exploded icmp can be expressed as a signed comparison to zero and updates the pre...
static Instruction * transformToIndexedCompare(GEPOperator *GEPLHS, Value *RHS, CmpPredicate Cond, const DataLayout &DL, InstCombiner &IC)
Converts (CMP GEPLHS, RHS) if this change would make RHS a constant.
static Instruction * foldCtpopPow2Test(ICmpInst &I, IntrinsicInst *CtpopLhs, const APInt &CRhs, InstCombiner::BuilderTy &Builder, const SimplifyQuery &Q)
static Instruction * foldFCmpFAbsFSubIntToFP(FCmpInst &I, InstCombinerImpl &IC)
Fold: fabs(uitofp(a) - uitofp(b)) pred C --> a == b where 'pred' is olt, ult, ogt,...
static void setInsertionPoint(IRBuilder<> &Builder, Value *V, bool Before=true)
static bool isNeutralValue(Instruction::BinaryOps BinaryOp, Value *RHS, bool IsSigned)
static bool isMultipleOf(Value *X, const APInt &C, const SimplifyQuery &Q)
Return true if X is a multiple of C.
static Value * foldICmpWithTruncSignExtendedVal(ICmpInst &I, InstCombiner::BuilderTy &Builder)
Some comparisons can be simplified.
static Instruction * foldICmpOrXX(ICmpInst &I, const SimplifyQuery &Q, InstCombinerImpl &IC)
This file provides internal interfaces used to implement the InstCombine.
This file provides the interface for the instcombine pass implementation.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
uint64_t IntrinsicInst * II
MachineBasicBlock * Folded
SmallVector< MachineOperand, 4 > Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This file implements a set that has insertion order iteration characteristics.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static SymbolRef::Type getType(const Symbol *Sym)
cmpResult
IEEE-754R 5.11: Floating Point Comparison Relations.
static constexpr roundingMode rmTowardZero
static constexpr roundingMode rmNearestTiesToEven
static LLVM_ABI ExponentType semanticsMaxExponent(const fltSemantics &)
opStatus
IEEE-754R 7: Default exception handling.
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
static APFloat getOne(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative One.
static APFloat getSmallestNormalized(const fltSemantics &Sem, bool Negative=false)
Returns the smallest (by magnitude) normalized finite number in the given semantics.
APInt bitcastToAPInt() const
static APFloat getLargest(const fltSemantics &Sem, bool Negative=false)
Returns the largest finite number in the given semantics.
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
opStatus next(bool nextDown)
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
LLVM_ABI FPClassTest classify() const
Return the FPClassTest which will return true for the value.
opStatus roundToIntegral(roundingMode RM)
Class for arbitrary precision integers.
LLVM_ABI APInt udiv(const APInt &RHS) const
Unsigned division operation.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
static LLVM_ABI void udivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder)
Dual division/remainder interface.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
bool isMinSignedValue() const
Determine if this is the smallest signed value.
uint64_t getZExtValue() const
Get zero extended value.
unsigned getActiveBits() const
Compute the number of active bits in the value.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
APInt abs() const
Get the absolute value.
unsigned ceilLogBase2() const
bool sgt(const APInt &RHS) const
Signed greater than comparison.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
LLVM_ABI APInt usub_ov(const APInt &RHS, bool &Overflow) const
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isSignMask() const
Check if the APInt's value is returned by getSignMask.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
static APInt getMinValue(unsigned numBits)
Gets minimum unsigned value of APInt for a specific bit width.
bool isNegative() const
Determine sign of this APInt.
LLVM_ABI APInt sadd_ov(const APInt &RHS, bool &Overflow) const
bool eq(const APInt &RHS) const
Equality comparison.
LLVM_ABI APInt sdiv(const APInt &RHS) const
Signed division function for APInt.
LLVM_ABI APInt uadd_ov(const APInt &RHS, bool &Overflow) const
void negate()
Negate this APInt in place.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countl_zero() const
The APInt version of std::countl_zero.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
bool isStrictlyPositive() const
Determine if this APInt Value is positive.
void flipAllBits()
Toggle every bit to its opposite value.
unsigned countl_one() const
Count the number of leading one bits.
unsigned logBase2() const
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
bool isMaxSignedValue() const
Determine if this is the largest signed value.
bool ule(const APInt &RHS) const
Unsigned less or equal comparison.
APInt shl(unsigned shiftAmt) const
Left-shift function.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
bool sge(const APInt &RHS) const
Signed greater or equal comparison.
LLVM_ABI APInt ssub_ov(const APInt &RHS, bool &Overflow) const
bool isOne() const
Determine if this is a value of 1.
static APInt getBitsSetFrom(unsigned numBits, unsigned loBit)
Constructs an APInt value that has a contiguous range of bits set.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
unsigned countr_one() const
Count the number of trailing one bits.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
An arbitrary precision integer that knows its signedness.
static APSInt getMinValue(uint32_t numBits, bool Unsigned)
Return the APSInt representing the minimum integer value with the given bit width and signedness.
static APSInt getMaxValue(uint32_t numBits, bool Unsigned)
Return the APSInt representing the maximum integer value with the given bit width and signedness.
an instruction to allocate memory on the stack
Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
Value * getArgOperand(unsigned i) const
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
This class is the base class for the comparison instructions.
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate getStrictPredicate() const
For example, SGE -> SGT, SLE -> SLT, ULE -> ULT, UGE -> UGT.
bool isEquality() const
Determine if this is an equals/not equals predicate.
static LLVM_ABI Predicate getFlippedStrictnessPredicate(Predicate pred)
This is a static version that you can use without an instruction available.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ ICMP_ULT
unsigned less than
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
static LLVM_ABI bool isEquality(Predicate pred)
Determine if this is an equals/not equals predicate.
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
bool isTrueWhenEqual() const
This is just a convenience.
static LLVM_ABI CmpInst * Create(OtherOps Op, Predicate Pred, Value *S1, Value *S2, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Construct a compare instruction, given the opcode, the predicate and the two operands.
Predicate getNonStrictPredicate() const
For example, SGT -> SGE, SLT -> SLE, ULT -> ULE, UGT -> UGE.
static LLVM_ABI bool isStrictPredicate(Predicate predicate)
This is a static version that you can use without an instruction available.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Predicate getPredicate() const
Return the predicate for this instruction.
static bool isIntPredicate(Predicate P)
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
static LLVM_ABI CmpPredicate getSwapped(CmpPredicate P)
Get the swapped predicate of a CmpPredicate.
Conditional Branch instruction.
static LLVM_ABI Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getPointerBitCastOrAddrSpaceCast(Constant *C, Type *Ty)
Create a BitCast or AddrSpaceCast for a pointer type depending on the address space.
static LLVM_ABI Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI Constant * getNot(Constant *C)
static LLVM_ABI Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getXor(Constant *C1, Constant *C2)
static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)
static LLVM_ABI ConstantFP * getZero(Type *Ty, bool Negative=false)
This is the shared class of boolean and integer constants.
uint64_t getLimitedValue(uint64_t Limit=~0ULL) const
getLimitedValue - If the value is smaller than the specified limit, return it, otherwise return the l...
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
unsigned getBitWidth() const
getBitWidth - Return the scalar bitwidth of this constant.
const APInt & getValue() const
Return the constant as an APInt value reference.
static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)
This class represents a range of values.
LLVM_ABI ConstantRange add(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an addition of a value in this ran...
LLVM_ABI bool getEquivalentICmp(CmpInst::Predicate &Pred, APInt &RHS) const
Set up Pred and RHS such that ConstantRange::makeExactICmpRegion(Pred, RHS) == *this.
LLVM_ABI ConstantRange subtract(const APInt &CI) const
Subtract the specified constant from the endpoints of this constant range.
const APInt * getSingleElement() const
If this set contains a single element, return it, otherwise return null.
LLVM_ABI ConstantRange difference(const ConstantRange &CR) const
Subtract the specified range from this range (aka relative complement of the sets).
LLVM_ABI bool isEmptySet() const
Return true if this set contains no members.
LLVM_ABI ConstantRange truncate(uint32_t BitWidth, unsigned NoWrapKind=0) const
Return a new range in the specified integer type, which must be strictly smaller than the current typ...
static LLVM_ABI ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)
Produce the exact range such that all values in the returned range satisfy the given predicate with a...
LLVM_ABI ConstantRange inverse() const
Return a new range that is the logical not of the current set.
LLVM_ABI ConstantRange intersectWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the intersection of this range with another range.
static ConstantRange getNonEmpty(APInt Lower, APInt Upper)
Create non-empty constant range with the given bounds.
LLVM_ABI ConstantRange sub(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a subtraction of a value in this r...
static LLVM_ABI ConstantRange makeExactNoWrapRegion(Instruction::BinaryOps BinOp, const APInt &Other, unsigned NoWrapKind)
Produce the range that contains X if and only if "X BinOp Other" does not wrap.
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
This is an important base class in LLVM.
static LLVM_ABI Constant * getIntegerValue(Type *Ty, const APInt &V)
Return the value for an integer or pointer constant, or a vector thereof, with the given scalar value...
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
LLVM_ABI bool isAllOnesValue() const
Return true if this is the value that would be returned by getAllOnesValue.
LLVM_ABI const APInt & getUniqueInteger() const
If C is a constant integer then return its value, otherwise C must be a vector of constant integers,...
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
iterator find(const_arg_type_t< KeyT > Val)
This instruction compares its operands according to the predicate given to the constructor.
static bool isCommutative(Predicate Pred)
static bool isEquality(Predicate Pred)
Represents flags for the getelementptr instruction/expression.
bool hasNoUnsignedSignedWrap() const
bool hasNoUnsignedWrap() const
GEPNoWrapFlags intersectForOffsetAdd(GEPNoWrapFlags Other) const
Given (gep (gep p, x), y), determine the nowrap flags for (gep p, x+y).
static GEPNoWrapFlags none()
bool isInBounds() const
Test whether this is an inbounds GEP, as defined by LangRef.html.
LLVM_ABI Type * getSourceElementType() const
Value * getPointerOperand()
GEPNoWrapFlags getNoWrapFlags() const
bool hasAllConstantIndices() const
Return true if all of the indices of this GEP are constant integers.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
This instruction compares its operands according to the predicate given to the constructor.
static bool isGE(Predicate P)
Return true if the predicate is SGE or UGE.
static LLVM_ABI bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
static bool isLT(Predicate P)
Return true if the predicate is SLT or ULT.
static bool isGT(Predicate P)
Return true if the predicate is SGT or UGT.
Predicate getFlippedSignednessPredicate() const
For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->EQ.
Predicate getSignedPredicate() const
For example, EQ->EQ, SLE->SLE, UGT->SGT, etc.
bool isEquality() const
Return true if this predicate is either EQ or NE.
static bool isEquality(Predicate P)
Return true if this predicate is either EQ or NE.
bool isRelational() const
Return true if the predicate is relational (not EQ or NE).
Predicate getUnsignedPredicate() const
For example, EQ->EQ, SLE->ULE, UGT->UGT, etc.
static bool isLE(Predicate P)
Return true if the predicate is SLE or ULE.
Common base class shared among various IRBuilders.
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
ConstantInt * getInt(const APInt &AI)
Get a constant integer value.
LLVM_ABI Value * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *Op, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 1 operand which is mangled on its type.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Instruction * foldICmpShrConstant(ICmpInst &Cmp, BinaryOperator *Shr, const APInt &C)
Fold icmp ({al}shr X, Y), C.
Instruction * foldICmpWithZextOrSext(ICmpInst &ICmp)
Instruction * foldICmpSelectConstant(ICmpInst &Cmp, SelectInst *Select, ConstantInt *C)
Instruction * foldICmpSRemConstant(ICmpInst &Cmp, BinaryOperator *UDiv, const APInt &C)
Instruction * foldICmpBinOpWithConstant(ICmpInst &Cmp, BinaryOperator *BO, const APInt &C)
Fold an icmp with BinaryOp and constant operand: icmp Pred BO, C.
Instruction * foldICmpOrConstant(ICmpInst &Cmp, BinaryOperator *Or, const APInt &C)
Fold icmp (or X, Y), C.
Instruction * foldICmpTruncWithTruncOrExt(ICmpInst &Cmp, const SimplifyQuery &Q)
Fold icmp (trunc nuw/nsw X), (trunc nuw/nsw Y).
Instruction * foldSignBitTest(ICmpInst &I)
Fold equality-comparison between zero and any (maybe truncated) right-shift by one-less-than-bitwidth...
Instruction * foldOpIntoPhi(Instruction &I, PHINode *PN, bool AllowMultipleUses=false)
Given a binary operator, cast instruction, or select which has a PHI node as operand #0,...
Value * insertRangeTest(Value *V, const APInt &Lo, const APInt &Hi, bool isSigned, bool Inside)
Emit a computation of: (V >= Lo && V < Hi) if Inside is true, otherwise (V < Lo || V >= Hi).
Instruction * foldICmpBinOp(ICmpInst &Cmp, const SimplifyQuery &SQ)
Try to fold icmp (binop), X or icmp X, (binop).
Instruction * foldICmpSubConstant(ICmpInst &Cmp, BinaryOperator *Sub, const APInt &C)
Fold icmp (sub X, Y), C.
Instruction * foldICmpWithClamp(ICmpInst &Cmp, Value *X, MinMaxIntrinsic *Min)
Match and fold patterns like: icmp eq/ne X, min(max(X, Lo), Hi) which represents a range check and ca...
Instruction * foldICmpInstWithConstantNotInt(ICmpInst &Cmp)
Handle icmp with constant (but not simple integer constant) RHS.
bool matchCommonBinOpOperands(Value *Op0, Value *Op1, CmpInst::Predicate Pred, Value *&LHS, Value *&RHS, const SimplifyQuery &Q)
Match Op0 Pred Op1 on binops with a removable common operand.
bool SimplifyDemandedBits(Instruction *I, unsigned Op, const APInt &DemandedMask, KnownBits &Known, const SimplifyQuery &Q, unsigned Depth=0) override
This form of SimplifyDemandedBits simplifies the specified instruction operand if possible,...
Instruction * foldICmpShlConstConst(ICmpInst &I, Value *ShAmt, const APInt &C1, const APInt &C2)
Handle "(icmp eq/ne (shl AP2, A), AP1)" -> (icmp eq/ne A, TrailingZeros(AP1) - TrailingZeros(AP2)).
Value * reassociateShiftAmtsOfTwoSameDirectionShifts(BinaryOperator *Sh0, const SimplifyQuery &SQ, bool AnalyzeForSignBitExtraction=false)
Instruction * foldICmpEqIntrinsicWithConstant(ICmpInst &ICI, IntrinsicInst *II, const APInt &C)
Fold an equality icmp with LLVM intrinsic and constant operand.
Instruction * FoldOpIntoSelect(Instruction &Op, SelectInst *SI, bool FoldWithMultiUse=false, bool SimplifyBothArms=false)
Given an instruction with a select as one operand and a constant as the other operand,...
Value * foldMultiplicationOverflowCheck(ICmpInst &Cmp)
Fold (-1 u/ x) u< y ((x * y) ?
Instruction * foldICmpWithConstant(ICmpInst &Cmp)
Fold icmp Pred X, C.
OverflowResult computeOverflow(Instruction::BinaryOps BinaryOp, bool IsSigned, Value *LHS, Value *RHS, Instruction *CtxI) const
CmpInst * canonicalizeICmpPredicate(CmpInst &I)
If we have a comparison with a non-canonical predicate, if we can update all the users,...
Instruction * eraseInstFromFunction(Instruction &I) override
Combiner aware instruction erasure.
Instruction * foldICmpWithZero(ICmpInst &Cmp)
Instruction * foldICmpBinOpEqualityWithConstant(ICmpInst &Cmp, BinaryOperator *BO, const APInt &C)
Fold an icmp equality instruction with binary operator LHS and constant RHS: icmp eq/ne BO,...
Instruction * foldICmpUsingBoolRange(ICmpInst &I)
If one operand of an icmp is effectively a bool (value range of {0,1}), then try to reduce patterns b...
Instruction * foldICmpWithTrunc(ICmpInst &Cmp)
Instruction * foldCmpSelectOfConstants(CmpInst &I)
Fold fcmp/icmp pred (select C1, TV1, FV1), (select C2, TV2, FV2) where all true/false values are cons...
Instruction * foldICmpIntrinsicWithConstant(ICmpInst &ICI, IntrinsicInst *II, const APInt &C)
Fold an icmp with LLVM intrinsic and constant operand: icmp Pred II, C.
bool matchThreeWayIntCompare(SelectInst *SI, Value *&LHS, Value *&RHS, ConstantInt *&Less, ConstantInt *&Equal, ConstantInt *&Greater)
Match a select chain which produces one of three values based on whether the LHS is less than,...
const InstCombineCLOptions & CLOpts
Instruction * visitFCmpInst(FCmpInst &I)
Instruction * foldICmpUsingKnownBits(ICmpInst &Cmp)
Try to fold the comparison based on range information we can get by checking whether bits are known t...
Instruction * foldICmpDivConstant(ICmpInst &Cmp, BinaryOperator *Div, const APInt &C)
Fold icmp ({su}div X, Y), C.
Instruction * foldIRemByPowerOfTwoToBitTest(ICmpInst &I)
If we have: icmp eq/ne (urem/srem x, y), 0 iff y is a power-of-two, we can replace this with a bit te...
Instruction * foldFCmpIntToFPConst(FCmpInst &I, Instruction *LHSI, Constant *RHSC)
Fold fcmp ([us]itofp x, cst) if possible.
Instruction * foldICmpUDivConstant(ICmpInst &Cmp, BinaryOperator *UDiv, const APInt &C)
Fold icmp (udiv X, Y), C.
Instruction * foldICmpAddOpConst(Value *X, const APInt &C, CmpPredicate Pred)
Fold "icmp pred (X+C), X".
Instruction * foldICmpWithCastOp(ICmpInst &ICmp)
Handle icmp (cast x), (cast or constant).
Instruction * foldICmpTruncConstant(ICmpInst &Cmp, TruncInst *Trunc, const APInt &C)
Fold icmp (trunc X), C.
Instruction * foldCmpLoadFromIndexedGlobal(LoadInst *LI, GetElementPtrInst *GEP, CmpPredicate Pred, Constant *RHSC, Instruction &CtxI, ConstantInt *AndCst=nullptr)
This is called when we see this pattern: cmp pred (load (gep GV, ...)), cmpcst where GV is a global v...
Instruction * foldICmpAddConstant(ICmpInst &Cmp, BinaryOperator *Add, const APInt &C)
Fold icmp (add X, Y), C.
Instruction * foldICmpMulConstant(ICmpInst &Cmp, BinaryOperator *Mul, const APInt &C)
Fold icmp (mul X, Y), C.
Instruction * foldICmpCommutative(CmpPredicate Pred, Value *Op0, Value *Op1, ICmpInst &CtxI)
Instruction * tryFoldInstWithCtpopWithNot(Instruction *I)
Instruction * foldICmpXorConstant(ICmpInst &Cmp, BinaryOperator *Xor, const APInt &C)
Fold icmp (xor X, Y), C.
Instruction * foldSelectICmp(CmpPredicate Pred, SelectInst *SI, Value *RHS, const ICmpInst &I)
Instruction * foldICmpInstWithConstantAllowPoison(ICmpInst &Cmp, const APInt &C)
Try to fold integer comparisons with a constant operand: icmp Pred X, C where X is some kind of instr...
Instruction * foldIsMultipleOfAPowerOfTwo(ICmpInst &Cmp)
Fold icmp eq (num + mask) & ~mask, num to icmp eq (and num, mask), 0 Where mask is a low bit mask.
Instruction * foldICmpAndShift(ICmpInst &Cmp, BinaryOperator *And, const APInt &C1, const APInt &C2)
Fold icmp (and (sh X, Y), C2), C1.
Instruction * foldICmpBinOpWithConstantViaTruthTable(ICmpInst &Cmp, BinaryOperator *BO, const APInt &C)
Instruction * foldICmpInstWithConstant(ICmpInst &Cmp)
Try to fold integer comparisons with a constant operand: icmp Pred X, C where X is some kind of instr...
Instruction * foldICmpXorShiftConst(ICmpInst &Cmp, BinaryOperator *Xor, const APInt &C)
For power-of-2 C: ((X s>> ShiftC) ^ X) u< C --> (X + C) u< (C << 1) ((X s>> ShiftC) ^ X) u> (C - 1) -...
Instruction * foldICmpShlConstant(ICmpInst &Cmp, BinaryOperator *Shl, const APInt &C)
Fold icmp (shl X, Y), C.
Instruction * foldICmpAndConstant(ICmpInst &Cmp, BinaryOperator *And, const APInt &C)
Fold icmp (and X, Y), C.
Instruction * foldICmpEquality(ICmpInst &Cmp)
Instruction * foldICmpWithMinMax(Instruction &I, MinMaxIntrinsic *MinMax, Value *Z, CmpPredicate Pred)
Fold icmp Pred min|max(X, Y), Z.
bool dominatesAllUses(const Instruction *DI, const Instruction *UI, const BasicBlock *DB) const
True when DB dominates all uses of DI except UI.
bool foldAllocaCmp(AllocaInst *Alloca)
Instruction * visitICmpInst(ICmpInst &I)
Instruction * foldICmpWithDominatingICmp(ICmpInst &Cmp)
Canonicalize icmp instructions based on dominating conditions.
bool replacedSelectWithOperand(SelectInst *SI, const ICmpInst *Icmp, const unsigned SIOpd)
Try to replace select with select operand SIOpd in SI-ICmp sequence.
Instruction * foldICmpShrConstConst(ICmpInst &I, Value *ShAmt, const APInt &C1, const APInt &C2)
Handle "(icmp eq/ne (ashr/lshr AP2, A), AP1)" -> (icmp eq/ne A, Log2(AP2/AP1)) -> (icmp eq/ne A,...
void freelyInvertAllUsersOf(Value *V, Value *IgnoredUser=nullptr)
Freely adapt every user of V as-if V was changed to !V.
Instruction * foldICmpAndConstConst(ICmpInst &Cmp, BinaryOperator *And, const APInt &C1)
Fold icmp (and X, C2), C1.
Instruction * foldICmpBitCast(ICmpInst &Cmp)
Instruction * foldGEPICmp(GEPOperator *GEPLHS, Value *RHS, CmpPredicate Cond, Instruction &I)
Fold comparisons between a GEP instruction and something else.
The core instruction combiner logic.
OverflowResult computeOverflowForSignedMul(const Value *LHS, const Value *RHS, const Instruction *CtxI) const
Module & getModule() const
LLVM_ABI bool canBeCastedExactlyIntToFP(Value *V, Type *FPTy, bool IsSigned, const Instruction *CtxI=nullptr) const
bool isFreeToInvert(Value *V, bool WillInvertAllUses, bool &DoesConsume)
Return true if the specified value is free to invert (apply ~ to).
static unsigned getComplexity(Value *V)
Assign a complexity or rank value to LLVM Values.
unsigned ComputeMaxSignificantBits(const Value *Op, const Instruction *CtxI=nullptr, unsigned Depth=0) const
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, const Instruction *CtxI=nullptr, unsigned Depth=0)
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
static Constant * SubOne(Constant *C)
Subtract one from a Constant.
OverflowResult computeOverflowForUnsignedSub(const Value *LHS, const Value *RHS, const Instruction *CtxI) const
static bool isCanonicalPredicate(CmpPredicate Pred)
Predicate canonicalization reduces the number of patterns that need to be matched by other transforms...
IRBuilder< TargetFolder, IRBuilderInstCombineInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
bool canFreelyInvertAllUsersOf(Instruction *V, Value *IgnoredUser)
Given i1 V, can every user of V be freely adapted if V is changed to !V ?
OverflowResult computeOverflowForSignedAdd(const WithCache< const Value * > &LHS, const WithCache< const Value * > &RHS, const Instruction *CtxI) const
void addToWorklist(Instruction *I)
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
OverflowResult computeOverflowForUnsignedMul(const Value *LHS, const Value *RHS, const Instruction *CtxI, bool IsNSW=false) const
OverflowResult computeOverflowForSignedSub(const Value *LHS, const Value *RHS, const Instruction *CtxI) const
OverflowResult computeOverflowForUnsignedAdd(const WithCache< const Value * > &LHS, const WithCache< const Value * > &RHS, const Instruction *CtxI) const
void computeKnownBits(const Value *V, KnownBits &Known, const Instruction *CtxI, unsigned Depth=0) const
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
const SimplifyQuery & getSimplifyQuery() const
LLVM_ABI bool hasNoNaNs() const LLVM_READONLY
Determine whether the no-NaNs flag is set.
LLVM_ABI bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
LLVM_ABI bool hasNoInfs() const LLVM_READONLY
Determine whether the no-infs flag is set.
bool isArithmeticShift() const
Return true if this is an arithmetic shift right.
LLVM_ABI bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
LLVM_ABI bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
LLVM_ABI bool isExact() const LLVM_READONLY
Determine whether the exact flag is set.
iterator_range< user_iterator > users()
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
An instruction for reading from memory.
bool isVolatile() const
Return true if this is a load from a volatile memory location.
This class represents min/max intrinsics.
static bool isMin(Intrinsic::ID ID)
Whether the intrinsic is a smin or umin.
static bool isSigned(Intrinsic::ID ID)
Whether the intrinsic is signed or unsigned.
A Module instance is used to store all the information related to an LLVM module.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
Represents a saturating add/sub intrinsic.
This class represents the LLVM 'select' instruction.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
A vector that has set insertion semantics.
size_type size() const
Determine the number of elements in the SetVector.
bool contains(const_arg_type key) const
Check if the SetVector contains the given key.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This instruction constructs a fixed permutation of two input vectors.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
reverse_iterator rbegin()
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class represents a truncation of integer types.
bool hasNoSignedWrap() const
Test whether this operation is known to never undergo signed overflow, aka the nsw property.
bool hasNoUnsignedWrap() const
Test whether this operation is known to never undergo unsigned overflow, aka the nuw property.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
bool isPointerTy() const
True if this is an instance of PointerType.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isPPC_FP128Ty() const
Return true if this is powerpc long double.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
LLVM_ABI int getFPMantissaWidth() const
Return the width of the mantissa of this type.
LLVM_ABI const fltSemantics & getFltSemantics() const
A Use represents the edge between a Value definition and its users.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< user_iterator > users()
LLVM_ABI bool hasNUsesOrMore(unsigned N) const
Return true if this value has N uses or more.
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
iterator_range< use_iterator > uses()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
const ParentTy * getParent() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI APInt RoundingUDiv(const APInt &A, const APInt &B, APInt::Rounding RM)
Return A unsign-divided by B, rounded by the given rounding mode.
LLVM_ABI APInt RoundingSDiv(const APInt &A, const APInt &B, APInt::Rounding RM)
Return A sign-divided by B, rounded by the given rounding mode.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
auto m_PosZeroFP()
Matches a floating-point positive zero.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
AllOnesConstantMatch m_AllOnes()
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
match_unless< Pattern > m_Unless(const Pattern &P)
Match if the inner matcher does NOT match.
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
match_combine_and< Ty... > m_CombineAnd(const Ty &...Ps)
Combine pattern matchers matching all of Ps patterns.
cst_pred_ty< is_lowbit_mask > m_LowBitMask()
Match an integer or vector with only the low bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
cst_pred_ty< is_negative > m_Negative()
Match an integer or vector of negative values.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
cst_pred_ty< is_sign_mask > m_SignMask()
Match an integer or vector with only the sign bit(s) set.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FSub > m_FSub(const LHS &L, const RHS &R)
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power-of-2.
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
auto m_Sqrt(const Opnd0 &Op0)
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
match_combine_or< CastInst_match< OpTy, ZExtInst >, OpTy > m_ZExtOrSelf(const OpTy &Op)
bool match(Val *V, const Pattern &P)
BinOpPred_match< LHS, RHS, is_idiv_op > m_IDiv(const LHS &L, const RHS &R)
Matches integer division operations.
match_bind< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
match_deferred< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)
ap_match< APFloat > m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
CmpClass_match< LHS, RHS, ICmpInst, true > m_c_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap, true > m_c_NUWAdd(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWNeg(const ValTy &V)
Matches a 'Neg' as 'sub nsw 0, V'.
cst_pred_ty< is_nonnegative > m_NonNegative()
Match an integer or vector of non-negative values.
auto m_SMax(const Opnd0 &Op0, const Opnd1 &Op1)
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
auto m_BinOp()
Match an arbitrary binary operation and ignore it.
auto m_UMax(const Opnd0 &Op0, const Opnd1 &Op1)
ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)
Match a single index ExtractValue instruction.
BinOpPred_match< LHS, RHS, is_logical_shift_op > m_LogicalShift(const LHS &L, const RHS &R)
Matches logical shift operations.
match_combine_or< CastInst_match< OpTy, UIToFPInst >, CastInst_match< OpTy, SIToFPInst > > m_IToFP(const OpTy &Op)
auto m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Xor, true > m_c_Xor(const LHS &L, const RHS &R)
Matches an Xor with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::FAdd > m_FAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
auto m_Constant()
Match an arbitrary Constant and ignore it.
NoWrapTrunc_match< OpTy, TruncInst::NoSignedWrap > m_NSWTrunc(const OpTy &Op)
Matches trunc nsw.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
cst_pred_ty< is_non_zero_int > m_NonZeroInt()
Match a non-zero integer or a vector with all non-zero elements.
ThreeOps_match< decltype(m_Value()), LHS, RHS, Instruction::Select, true > m_c_Select(const LHS &L, const RHS &R)
Match Select(C, LHS, RHS) or Select(C, RHS, LHS)
CastInst_match< OpTy, FPExtInst > m_FPExt(const OpTy &Op)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoSignedWrap > m_NSWShl(const LHS &L, const RHS &R)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWShl(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWMul(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::UDiv > m_UDiv(const LHS &L, const RHS &R)
is_zero< true > m_Zero()
Match any null constant or a vector with all elements equal to 0.
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
cst_pred_ty< is_negated_power2_or_zero > m_NegatedPower2OrZero()
Match a integer or vector negated power-of-2.
NoWrapTrunc_match< OpTy, TruncInst::NoUnsignedWrap > m_NUWTrunc(const OpTy &Op)
Matches trunc nuw.
cst_pred_ty< custom_checkfn< APInt > > m_CheckedInt(function_ref< bool(const APInt &)> CheckFn)
Match an integer or vector where CheckFn(ele) for each element is true.
SelectLike_match< CondTy, LTy, RTy > m_SelectLike(const CondTy &C, const LTy &TrueC, const RTy &FalseC)
Matches a value that behaves like a boolean-controlled select, i.e.
cst_pred_ty< is_lowbit_mask_or_zero > m_LowBitMaskOrZero()
Match an integer or vector with only the low bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
match_combine_or< BinaryOp_match< LHS, RHS, Instruction::Add >, DisjointOr_match< LHS, RHS > > m_AddLike(const LHS &L, const RHS &R)
Match either "add" or "or disjoint".
CastInst_match< OpTy, UIToFPInst > m_UIToFP(const OpTy &Op)
CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
cstfp_pred_ty< is_finitenonzero > m_FiniteNonZero()
Match a finite non-zero FP constant.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)
auto m_SMin(const Opnd0 &Op0, const Opnd1 &Op1)
auto m_FAbs(const Opnd0 &Op0)
Signum_match< Val_t > m_Signum(const Val_t &V)
Matches a signum pattern.
CastInst_match< OpTy, SIToFPInst > m_SIToFP(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > > m_ZExtOrSExt(const OpTy &Op)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
UAddWithOverflow_match< LHS_t, RHS_t, Sum_t > m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S)
Match an icmp instruction checking for unsigned overflow on addition.
BinOpPred_match< LHS, RHS, is_irem_op > m_IRem(const LHS &L, const RHS &R)
Matches integer remainder operations.
auto m_MaxOrMin(const Opnd0 &Op0, const Opnd1 &Op1)
CastInst_match< OpTy, FPTruncInst > m_FPTrunc(const OpTy &Op)
auto m_Undef()
Match an arbitrary undef constant.
auto m_VecReverse(const Opnd0 &Op0)
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
ElementWiseBitCast_match< OpTy > m_ElementWiseBitCast(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
CastOperator_match< OpTy, Instruction::PtrToInt > m_PtrToInt(const OpTy &Op)
Matches PtrToInt.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
cst_pred_ty< icmp_pred_with_threshold > m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold)
Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
This is an optimization pass for GlobalISel generic memory operations.
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
@ NeverOverflows
Never overflows.
@ AlwaysOverflowsHigh
Always overflows in the direction of signed/unsigned max value.
@ AlwaysOverflowsLow
Always overflows in the direction of signed/unsigned min value.
@ MayOverflow
May or may not overflow.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isKnownNeverInfinity(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point scalar value is not an infinity or if the floating-point vector val...
LLVM_ABI bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS, bool &TrueIfSigned)
Given an exploded icmp instruction, return true if the comparison only checks the sign bit.
@ Known
Known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ BinaryOp
One of the operands is a binary op.
LLVM_ABI Value * stripNullTest(Value *V)
Returns the inner value X if the expression has the form f(X) where f(X) == 0 if and only if X == 0,...
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
LLVM_ABI Value * simplifyFCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q)
Given operands for an FCmpInst, fold the result or return null.
int ilogb(const APFloat &Arg)
Returns the exponent of the internal representation of the APFloat.
LLVM_ABI bool isKnownNegative(const WithCache< const Value * > &V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the given value is known be negative (i.e.
LLVM_ABI bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Return true if the given value is known to have exactly one bit set when defined.
LLVM_ABI bool MaskedValueIsZero(const Value *V, const APInt &Mask, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if 'V & Mask' is known to be zero.
LLVM_ABI Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Function *CtxF=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
LLVM_ABI Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for an Add, fold the result or return null.
LLVM_ABI Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)
Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
LLVM_ABI Value * emitGEPOffset(IRBuilderBase *Builder, const DataLayout &DL, User *GEP, bool NoAssumptions=false)
Given a getelementptr instruction/constantexpr, emit the code necessary to compute the offset from th...
constexpr unsigned MaxAnalysisRecursionDepth
LLVM_ABI Constant * ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op, const DataLayout &DL)
Attempt to constant fold a unary operation with the specified operand.
SelectPatternFlavor
Specific patterns of select instructions we can match.
@ SPF_FMAXNUM
Floating point minnum.
@ SPF_FMINNUM
Unsigned maximum.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI bool isKnownPositive(const WithCache< const Value * > &V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the given value is known be positive (i.e.
LLVM_ABI bool impliesPoison(const Value *ValAssumedPoison, const Value *V)
Return true if V is poison given that ValAssumedPoison is already poison.
LLVM_ABI LinearExpression decomposeLinearExpression(const DataLayout &DL, Value *Ptr)
Decompose a pointer into a linear expression.
LLVM_ABI bool isFinite(const Loop *L)
Return true if this loop can be assumed to run for a finite number of iterations.
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode RM)
Returns: X * 2^Exp for integral exponents.
LLVM_ABI bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Value * simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an ICmpInst, fold the result or return null.
LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
LLVM_ABI Constant * ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset, const DataLayout &DL)
Extract value of C at the given Offset reinterpreted as Ty.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
LLVM_ABI Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
@ UMin
Unsigned integer min implemented in terms of select(cmp()).
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ SMax
Signed integer max implemented in terms of select(cmp()).
@ SMin
Signed integer min implemented in terms of select(cmp()).
@ Sub
Subtraction of integers.
@ UMax
Unsigned integer max implemented in terms of select(cmp()).
LLVM_ABI bool isKnownNonEqual(const Value *V1, const Value *V2, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the given values are known to be non-equal when defined.
DWARFExpression::Operation Op
LLVM_ABI bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, unsigned MaxUsesToExplore=0)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
constexpr unsigned BitWidth
LLVM_ABI Constant * getLosslessInvCast(Constant *C, Type *InvCastTo, unsigned CastOp, const DataLayout &DL, PreservedCastFlags *Flags=nullptr)
Try to cast C to InvC losslessly, satisfying CastOp(InvC) equals C, or CastOp(InvC) is a refined valu...
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
LLVM_ABI bool isKnownNeverInfOrNaN(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point value can never contain a NaN or infinity.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isKnownNeverNaN(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...
LLVM_ABI std::optional< std::pair< CmpPredicate, Constant * > > getFlippedStrictnessPredicateAndConstant(CmpPredicate Pred, Constant *C)
Convert an integer comparison with a constant RHS into an equivalent form with the strictness flipped...
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
@ End
Run the machine verifier once, at the end of the pipeline.
LLVM_ABI bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the give value is known to be non-negative.
LLVM_ABI SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr)
Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind and providing the out param...
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
LLVM_ABI std::optional< bool > isImpliedCondition(const Value *LHS, const Value *RHS, const DataLayout &DL, bool LHSIsTrue=true, unsigned Depth=0)
Return true if RHS is known to be implied true by LHS.
LLVM_ABI std::optional< DecomposedBitTest > decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate Pred, bool LookThroughTrunc=true, bool AllowNonZeroC=false, bool DecomposeAnd=false)
Decompose an icmp into the form ((X & Mask) pred C) if possible.
LLVM_ABI ConstantRange computeConstantRange(const Value *V, bool ForSigned, const SimplifyQuery &SQ, unsigned Depth=0)
Determine the possible constant range of an integer or vector of integer value.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Value * materialize(InstCombiner::BuilderTy &Builder) const
static OffsetResult select(Value *Cond, Value *TrueV, Value *FalseV, Instruction *MDFrom)
static OffsetResult value(Value *V)
static OffsetResult invalid()
This callback is used in conjunction with PointerMayBeCaptured.
static CommonPointerBase compute(Value *LHS, Value *RHS)
Represent subnormal handling kind for floating point instruction inputs and outputs.
@ PreserveSign
The sign of a flushed-to-zero number is preserved in the sign of 0.
@ PositiveZero
Denormals are flushed to positive zero.
static constexpr DenormalMode getIEEE()
bool isNonNegative() const
Returns true if this value is known to be non-negative.
bool isZero() const
Returns true if value is all zero.
unsigned countMinTrailingZeros() const
Returns the minimum number of trailing zero bits.
unsigned countMaxTrailingZeros() const
Returns the maximum number of trailing zero bits possible.
APInt getSignedMaxValue() const
Return the maximal signed value possible given these KnownBits.
unsigned countMaxPopulation() const
Returns the maximum number of bits that could be one.
bool isConstant() const
Returns true if we know the value of all bits.
unsigned countMinLeadingZeros() const
Returns the minimum number of leading zero bits.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
APInt getMinValue() const
Return the minimal unsigned value possible given these KnownBits.
bool isNegative() const
Returns true if this value is known to be negative.
unsigned countMinPopulation() const
Returns the number of bits known to be one.
APInt getSignedMinValue() const
Return the minimal signed value possible given these KnownBits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
Linear expression BasePtr + Index * Scale + Offset.
SelectPatternFlavor Flavor
static bool isMinOrMax(SelectPatternFlavor SPF)
When implementing this min/max pattern as fcmp; select, does the fcmp have to be ordered?
SimplifyQuery getWithInstruction(const Instruction *I) const
A MapVector that performs no allocations if smaller than a certain size.
Capture information for a specific Use.