23using namespace PatternMatch;
25#define DEBUG_TYPE "instcombine"
56 "Lo is not < Hi in range emission code!");
58 Type *Ty = V->getType();
63 if (
isSigned ?
Lo.isMinSignedValue() :
Lo.isMinValue()) {
120 const APInt *ConstA =
nullptr, *ConstB =
nullptr, *ConstC =
nullptr;
125 bool IsAPow2 = ConstA && ConstA->
isPowerOf2();
126 bool IsBPow2 = ConstB && ConstB->isPowerOf2();
127 unsigned MaskVal = 0;
128 if (ConstC && ConstC->isZero()) {
147 }
else if (ConstA && ConstC && ConstC->
isSubsetOf(*ConstA)) {
157 }
else if (ConstB && ConstC && ConstC->isSubsetOf(*ConstB)) {
188 Y = ConstantInt::get(
X->getType(), Mask);
189 Z = ConstantInt::get(
X->getType(), 0);
214 Value *L11, *L12, *L21, *L22;
217 L21 = L22 = L1 =
nullptr;
242 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
245 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
262 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
267 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
286 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
291 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
300 assert(Ok &&
"Failed to find AND on the right side of the RHS icmp.");
306 }
else if (L12 ==
A) {
309 }
else if (L21 ==
A) {
312 }
else if (L22 ==
A) {
319 return std::optional<std::pair<unsigned, unsigned>>(
320 std::make_pair(LeftType, RightType));
342 const APInt *BCst, *CCst, *DCst, *OrigECst;
353 APInt ECst = *OrigECst;
359 if (*BCst == 0 || *DCst == 0)
366 if ((*BCst & *DCst) == 0)
385 if ((((*BCst & *DCst) & ECst) == 0) &&
386 (*BCst & (*BCst ^ *DCst)).isPowerOf2()) {
387 APInt BorD = *BCst | *DCst;
388 APInt BandBxorDorE = (*BCst & (*BCst ^ *DCst)) | ECst;
389 Value *NewMask = ConstantInt::get(
A->getType(), BorD);
390 Value *NewMaskedValue = ConstantInt::get(
A->getType(), BandBxorDorE);
392 return Builder.
CreateICmp(NewCC, NewAnd, NewMaskedValue);
395 auto IsSubSetOrEqual = [](
const APInt *C1,
const APInt *C2) {
396 return (*C1 & *C2) == *C1;
398 auto IsSuperSetOrEqual = [](
const APInt *C1,
const APInt *C2) {
399 return (*C1 & *C2) == *C2;
408 if (!IsSubSetOrEqual(BCst, DCst) && !IsSuperSetOrEqual(BCst, DCst))
420 if (IsSubSetOrEqual(BCst, DCst))
421 return ConstantInt::get(
LHS->
getType(), !IsAnd);
431 if (IsSuperSetOrEqual(BCst, DCst))
436 assert(IsSubSetOrEqual(BCst, DCst) &&
"Precondition due to above code");
437 if ((*BCst & ECst) != 0)
443 return ConstantInt::get(
LHS->
getType(), !IsAnd);
455 "Expected equality predicates for masked type of icmps.");
468 PredL, PredR, Builder)) {
474 PredR, PredL, Builder)) {
486 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *E =
nullptr;
488 std::optional<std::pair<unsigned, unsigned>> MaskPair =
493 "Expected equality predicates for masked type of icmps.");
494 unsigned LHSMask = MaskPair->first;
495 unsigned RHSMask = MaskPair->second;
496 unsigned Mask = LHSMask & RHSMask;
501 LHS,
RHS, IsAnd,
A,
B,
C,
D, E, PredL, PredR, LHSMask, RHSMask,
537 return Builder.
CreateICmp(NewCC, NewAnd, Zero);
546 return Builder.
CreateICmp(NewCC, NewAnd, NewOr);
561 const APInt *ConstB, *ConstD;
571 APInt NewMask = *ConstB & *ConstD;
572 if (NewMask == *ConstB)
574 else if (NewMask == *ConstD)
583 APInt NewMask = *ConstB | *ConstD;
584 if (NewMask == *ConstB)
586 else if (NewMask == *ConstD)
613 const APInt *OldConstC, *OldConstE;
619 const APInt ConstC = PredL !=
CC ? *ConstB ^ *OldConstC : *OldConstC;
620 const APInt ConstE = PredR !=
CC ? *ConstD ^ *OldConstE : *OldConstE;
622 if (((*ConstB & *ConstD) & (ConstC ^ ConstE)).getBoolValue())
623 return IsNot ? nullptr : ConstantInt::get(
LHS->
getType(), !IsAnd);
625 if (IsNot && !ConstB->
isSubsetOf(*ConstD) && !ConstD->isSubsetOf(*ConstB))
630 BD = *ConstB & *ConstD;
631 CE = ConstC & ConstE;
633 BD = *ConstB | *ConstD;
634 CE = ConstC | ConstE;
637 Value *CEVal = ConstantInt::get(
A->getType(), CE);
642 return FoldBMixed(NewCC,
false);
644 return FoldBMixed(NewCC,
true);
690 default:
return nullptr;
706Value *InstCombinerImpl::foldAndOrOfICmpsOfAndWithPow2(
ICmpInst *LHS,
712 if (
LHS->getPredicate() != Pred ||
RHS->getPredicate() != Pred)
722 if (L1 ==
R2 || L2 ==
R2)
780 auto tryToMatchSignedTruncationCheck = [](
ICmpInst *ICmp,
Value *&
X,
781 APInt &SignBitMask) ->
bool {
783 const APInt *I01, *I1;
798 if (tryToMatchSignedTruncationCheck(ICmp1, X1, HighestBit))
800 else if (tryToMatchSignedTruncationCheck(ICmp0, X1, HighestBit))
805 assert(HighestBit.
isPowerOf2() &&
"expected to be power of two (non-zero)");
809 APInt &UnsetBitsMask) ->
bool {
813 Pred,
X, UnsetBitsMask,
821 UnsetBitsMask = *Mask;
830 if (!tryToDecompose(OtherICmp, X0, UnsetBitsMask))
833 assert(!UnsetBitsMask.
isZero() &&
"empty mask makes no sense.");
848 APInt SignBitsMask = ~(HighestBit - 1U);
855 if (!UnsetBitsMask.
isSubsetOf(SignBitsMask)) {
856 APInt OtherHighestBit = (~UnsetBitsMask) + 1U;
864 return Builder.
CreateICmpULT(
X, ConstantInt::get(
X->getType(), HighestBit),
865 CxtI.
getName() +
".simplified");
929 "Expected equality predicates for masked type of icmps.");
949 const APInt *BCst, *DCst, *ECst;
952 (isa<PoisonValue>(
B) ||
957 if (
const auto *BVTy = dyn_cast<VectorType>(
B->getType())) {
958 const auto *BFVTy = dyn_cast<FixedVectorType>(BVTy);
959 const auto *BConst = dyn_cast<Constant>(
B);
960 const auto *DConst = dyn_cast<Constant>(
D);
961 const auto *EConst = dyn_cast<Constant>(E);
963 if (!BFVTy || !BConst || !DConst || !EConst)
966 for (
unsigned I = 0;
I != BFVTy->getNumElements(); ++
I) {
967 const auto *BElt = BConst->getAggregateElement(
I);
968 const auto *DElt = DConst->getAggregateElement(
I);
969 const auto *EElt = EConst->getAggregateElement(
I);
971 if (!BElt || !DElt || !EElt)
973 if (!isReducible(BElt, DElt, EElt))
978 if (!isReducible(
B,
D, E))
996 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *E =
nullptr;
1002 std::optional<std::pair<unsigned, unsigned>> MaskPair =
1008 unsigned CmpMask0 = MaskPair->first;
1009 unsigned CmpMask1 = MaskPair->second;
1010 if ((CmpMask0 &
Mask_AllZeros) && (CmpMask1 == compareBMask)) {
1014 }
else if ((CmpMask0 == compareBMask) && (CmpMask1 &
Mask_AllZeros)) {
1025 ICmpInst *UnsignedICmp,
bool IsAnd,
1037 if (
match(UnsignedICmp,
1053 IsAnd && GetKnownNonZeroAndOther(
B,
A))
1056 !IsAnd && GetKnownNonZeroAndOther(
B,
A))
1073 return std::nullopt;
1075 unsigned NumOriginalBits =
X->getType()->getScalarSizeInBits();
1076 unsigned NumExtractedBits = V->getType()->getScalarSizeInBits();
1082 Shift->
ule(NumOriginalBits - NumExtractedBits))
1084 return {{
X, 0, NumExtractedBits}};
1092 Type *TruncTy = V->getType()->getWithNewBitWidth(
P.NumBits);
1093 if (TruncTy != V->getType())
1108 unsigned OpNo) -> std::optional<IntPart> {
1109 if (Pred ==
Cmp->getPredicate())
1118 return std::nullopt;
1127 return std::nullopt;
1129 return std::nullopt;
1134 return {{
I->getOperand(OpNo),
From,
C->getBitWidth() -
From}};
1137 std::optional<IntPart> L0 = GetMatchPart(Cmp0, 0);
1138 std::optional<IntPart> R0 = GetMatchPart(Cmp0, 1);
1139 std::optional<IntPart> L1 = GetMatchPart(Cmp1, 0);
1140 std::optional<IntPart> R1 = GetMatchPart(Cmp1, 1);
1141 if (!L0 || !R0 || !L1 || !R1)
1146 if (L0->From != L1->From || R0->From != R1->From) {
1147 if (L0->From != R1->From || R0->From != L1->From)
1154 if (L0->StartBit + L0->NumBits != L1->StartBit ||
1155 R0->StartBit + R0->NumBits != R1->StartBit) {
1156 if (L1->StartBit + L1->NumBits != L0->StartBit ||
1157 R1->StartBit + R1->NumBits != R0->StartBit)
1164 IntPart L = {L0->From, L0->StartBit, L0->NumBits + L1->NumBits};
1165 IntPart R = {R0->From, R0->StartBit, R0->NumBits + R1->NumBits};
1175 bool IsAnd,
bool IsLogical,
1204 if (!SubstituteCmp) {
1214 return Builder.
CreateBinOp(IsAnd ? Instruction::And : Instruction::Or, Cmp0,
1222Value *InstCombinerImpl::foldAndOrOfICmpsUsingRanges(
ICmpInst *ICmp1,
1227 const APInt *C1, *C2;
1234 const APInt *Offset1 =
nullptr, *Offset2 =
nullptr;
1269 if (!LowerDiff.
isPowerOf2() || LowerDiff != UpperDiff ||
1282 CR->getEquivalentICmp(NewPred, NewC,
Offset);
1314 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1315 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1324 FMF &=
RHS->getFastMathFlags();
1331 bool IsAnd,
bool IsLogicalSelect) {
1332 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1333 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1336 if (LHS0 == RHS1 && RHS0 == LHS1) {
1356 if (LHS0 == RHS0 && LHS1 == RHS1) {
1359 unsigned NewPred = IsAnd ? FCmpCodeL & FCmpCodeR : FCmpCodeL | FCmpCodeR;
1365 FMF &=
RHS->getFastMathFlags();
1372 if (!IsLogicalSelect &&
1403 auto [ClassValRHS, ClassMaskRHS] =
1406 auto [ClassValLHS, ClassMaskLHS] =
1408 if (ClassValLHS == ClassValRHS) {
1409 unsigned CombinedMask = IsAnd ? (ClassMaskLHS & ClassMaskRHS)
1410 : (ClassMaskLHS | ClassMaskRHS);
1412 Intrinsic::is_fpclass, {ClassValLHS->getType()},
1441 if (IsLessThanOrLessEqual(IsAnd ? PredR : PredL)) {
1445 if (IsLessThanOrLessEqual(IsAnd ? PredL : PredR)) {
1448 RHS->getFastMathFlags());
1452 ConstantFP::get(LHS0->
getType(), *LHSC));
1463 auto *FCmp = dyn_cast<FCmpInst>(
Op);
1464 if (!FCmp || !FCmp->hasOneUse())
1467 std::tie(ClassVal, ClassMask) =
1468 fcmpToClassTest(FCmp->getPredicate(), *FCmp->getParent()->getParent(),
1469 FCmp->getOperand(0), FCmp->getOperand(1));
1470 return ClassVal !=
nullptr;
1481 Value *ClassVal0 =
nullptr;
1482 Value *ClassVal1 =
nullptr;
1499 ClassVal0 == ClassVal1) {
1500 unsigned NewClassMask;
1502 case Instruction::And:
1503 NewClassMask = ClassMask0 & ClassMask1;
1505 case Instruction::Or:
1506 NewClassMask = ClassMask0 | ClassMask1;
1508 case Instruction::Xor:
1509 NewClassMask = ClassMask0 ^ ClassMask1;
1516 auto *II = cast<IntrinsicInst>(Op0);
1518 1, ConstantInt::get(II->getArgOperand(1)->getType(), NewClassMask));
1523 auto *II = cast<IntrinsicInst>(Op1);
1525 1, ConstantInt::get(II->getArgOperand(1)->getType(), NewClassMask));
1545Instruction *InstCombinerImpl::canonicalizeConditionalNegationViaMathToSelect(
1547 assert(
I.getOpcode() == BinaryOperator::Xor &&
"Only for xor!");
1552 !
Cond->getType()->isIntOrIntVectorTy(1) ||
1566 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1567 "Expecting and/or op for fcmp transform");
1587 Pred != NanPred ||
X->getType() !=
Y->getType())
1591 Pred != NanPred ||
X->getType() !=
Y->getType())
1597 if (
auto *NewFCmpInst = dyn_cast<FCmpInst>(NewFCmp)) {
1599 NewFCmpInst->copyIRFlags(Op0);
1600 NewFCmpInst->andIRFlags(BO10);
1611 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1612 "Trying to match De Morgan's Laws with something other than and/or");
1616 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1618 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1644bool InstCombinerImpl::shouldOptimizeCast(
CastInst *CI) {
1653 if (
const auto *PrecedingCI = dyn_cast<CastInst>(CastSrc))
1654 if (isEliminableCastPair(PrecedingCI, CI))
1680 return new ZExtInst(NewOp, DestTy);
1688 return new SExtInst(NewOp, DestTy);
1697 auto LogicOpc =
I.getOpcode();
1698 assert(
I.isBitwiseLogicOp() &&
"Unexpected opcode for bitwise logic folding");
1700 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1706 auto FoldBitwiseICmpZeroWithICmp = [&](
Value *Op0,
1722 auto *ICmpR = cast<ZExtInst>(Op1)->getOperand(0);
1728 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op0, Op1))
1731 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op1, Op0))
1734 CastInst *Cast0 = dyn_cast<CastInst>(Op0);
1740 Type *DestTy =
I.getType();
1748 CastInst *Cast1 = dyn_cast<CastInst>(Op1);
1765 unsigned XNumBits =
X->getType()->getScalarSizeInBits();
1766 unsigned YNumBits =
Y->getType()->getScalarSizeInBits();
1767 if (XNumBits < YNumBits)
1785 shouldOptimizeCast(Cast0) && shouldOptimizeCast(Cast1)) {
1796 assert(
I.getOpcode() == Instruction::And);
1797 Value *Op0 =
I.getOperand(0);
1798 Value *Op1 =
I.getOperand(1);
1806 return BinaryOperator::CreateXor(
A,
B);
1822 assert(
I.getOpcode() == Instruction::Or);
1823 Value *Op0 =
I.getOperand(0);
1824 Value *Op1 =
I.getOperand(1);
1849 return BinaryOperator::CreateXor(
A,
B);
1869 Value *Op0 =
And.getOperand(0), *Op1 =
And.getOperand(1);
1883 if (!isa<VectorType>(Ty) && !shouldChangeType(Ty,
X->getType()))
1890 if (Opc == Instruction::LShr || Opc == Instruction::Shl)
1907 assert(Opcode == Instruction::And || Opcode == Instruction::Or);
1911 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1913 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1920 const auto matchNotOrAnd =
1921 [Opcode, FlippedOpcode](
Value *
Op,
auto m_A,
auto m_B,
auto m_C,
1922 Value *&
X,
bool CountUses =
false) ->
bool {
1923 if (CountUses && !
Op->hasOneUse())
1930 return !CountUses ||
X->hasOneUse();
1946 return (Opcode == Instruction::Or)
1956 return (Opcode == Instruction::Or)
1979 if (Opcode == Instruction::Or && Op0->
hasOneUse() &&
1986 Value *
Or = cast<BinaryOperator>(
X)->getOperand(0);
2018 return (Opcode == Instruction::Or)
2020 : BinaryOperator::CreateOr(
Xor,
X);
2054 if (!isa<Constant>(
X) && !isa<Constant>(
Y) && !isa<Constant>(Z)) {
2056 if (!
X->hasOneUse()) {
2061 if (!
Y->hasOneUse()) {
2082 Type *Ty =
I.getType();
2084 Value *Op0 =
I.getOperand(0);
2085 Value *Op1 =
I.getOperand(1);
2097 case Instruction::And:
2098 if (
C->countl_one() < LastOneMath)
2101 case Instruction::Xor:
2102 case Instruction::Or:
2103 if (
C->countl_zero() < LastOneMath)
2112 ConstantInt::get(Ty, *C2), Op0);
2119 assert((
I.isBitwiseLogicOp() ||
I.getOpcode() == Instruction::Add) &&
2120 "Unexpected opcode");
2123 Constant *ShiftedC1, *ShiftedC2, *AddC;
2124 Type *Ty =
I.getType();
2138 auto *Op0Inst = dyn_cast<Instruction>(
I.getOperand(0));
2139 auto *Op1Inst = dyn_cast<Instruction>(
I.getOperand(1));
2140 if (!Op0Inst || !Op1Inst)
2146 if (ShiftOp != Op1Inst->getOpcode())
2150 if (
I.getOpcode() == Instruction::Add && ShiftOp != Instruction::Shl)
2170 assert(
I.isBitwiseLogicOp() &&
"Should and/or/xor");
2171 if (!
I.getOperand(0)->hasOneUse())
2178 if (
Y && (!
Y->hasOneUse() ||
X->getIntrinsicID() !=
Y->getIntrinsicID()))
2184 if (!
Y && (!(IID == Intrinsic::bswap || IID == Intrinsic::bitreverse) ||
2189 case Intrinsic::fshl:
2190 case Intrinsic::fshr: {
2191 if (
X->getOperand(2) !=
Y->getOperand(2))
2194 Builder.
CreateBinOp(
I.getOpcode(),
X->getOperand(0),
Y->getOperand(0));
2196 Builder.
CreateBinOp(
I.getOpcode(),
X->getOperand(1),
Y->getOperand(1));
2200 case Intrinsic::bswap:
2201 case Intrinsic::bitreverse: {
2203 I.getOpcode(),
X->getOperand(0),
2204 Y ?
Y->getOperand(0)
2205 : ConstantInt::get(
I.getType(), IID == Intrinsic::bswap
2224 unsigned Depth = 0) {
2231 auto *
I = dyn_cast<BinaryOperator>(V);
2232 if (!
I || !
I->isBitwiseLogicOp() ||
Depth >= 3)
2235 if (!
I->hasOneUse())
2236 SimplifyOnly =
true;
2239 SimplifyOnly, IC,
Depth + 1);
2241 SimplifyOnly, IC,
Depth + 1);
2242 if (!NewOp0 && !NewOp1)
2246 NewOp0 =
I->getOperand(0);
2248 NewOp1 =
I->getOperand(1);
2263 Type *Ty =
I.getType();
2297 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2332 Constant *NewC = ConstantInt::get(Ty, *
C & *XorC);
2335 return BinaryOperator::CreateXor(
And, NewC);
2346 APInt Together = *
C & *OrC;
2349 return BinaryOperator::CreateOr(
And, ConstantInt::get(Ty, Together));
2353 const APInt *ShiftC;
2355 ShiftC->
ult(Width)) {
2360 Constant *ShAmtC = ConstantInt::get(Ty, ShiftC->
zext(Width));
2361 return BinaryOperator::CreateLShr(Sext, ShAmtC);
2369 return BinaryOperator::CreateLShr(
X, ConstantInt::get(Ty, *ShiftC));
2377 if (Op0->
hasOneUse() &&
C->isPowerOf2() && (*AddC & (*
C - 1)) == 0) {
2378 assert((*
C & *AddC) != 0 &&
"Expected common bit");
2380 return BinaryOperator::CreateXor(NewAnd, Op1);
2387 switch (
B->getOpcode()) {
2388 case Instruction::Xor:
2389 case Instruction::Or:
2390 case Instruction::Mul:
2391 case Instruction::Add:
2392 case Instruction::Sub:
2408 C->isIntN(
X->getType()->getScalarSizeInBits())) {
2409 unsigned XWidth =
X->getType()->getScalarSizeInBits();
2410 Constant *TruncC1 = ConstantInt::get(
X->getType(), C1->
trunc(XWidth));
2414 Constant *TruncC = ConstantInt::get(
X->getType(),
C->trunc(XWidth));
2424 C->isMask(
X->getType()->getScalarSizeInBits())) {
2434 C->isMask(
X->getType()->getScalarSizeInBits())) {
2468 if (
C->isPowerOf2() &&
2471 int Log2C =
C->exactLogBase2();
2473 cast<BinaryOperator>(Op0)->getOpcode() == Instruction::Shl;
2474 int BitNum = IsShiftLeft ? Log2C - Log2ShiftC : Log2ShiftC - Log2C;
2475 assert(BitNum >= 0 &&
"Expected demanded bits to handle impossible mask");
2508 if (Cmp->isZeroValue()) {
2533 Attribute::NoImplicitFloat)) {
2549 X->getType()->getScalarSizeInBits())))) {
2551 return BinaryOperator::CreateAnd(SExt, Op1);
2557 if (
I.getType()->isIntOrIntVectorTy(1)) {
2558 if (
auto *SI0 = dyn_cast<SelectInst>(Op0)) {
2560 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
true))
2563 if (
auto *SI1 = dyn_cast<SelectInst>(Op1)) {
2565 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
true))
2580 return BinaryOperator::CreateAnd(Op0,
B);
2583 return BinaryOperator::CreateAnd(Op1,
B);
2591 if (NotC !=
nullptr)
2592 return BinaryOperator::CreateAnd(Op0, NotC);
2601 if (NotC !=
nullptr)
2611 return BinaryOperator::CreateAnd(
A,
B);
2619 return BinaryOperator::CreateAnd(
A,
B);
2648 bool IsLogical = isa<SelectInst>(Op1);
2650 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
2652 foldAndOrOfICmps(
LHS, Cmp,
I,
true, IsLogical))
2657 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
2658 if (
Value *Res = foldAndOrOfICmps(
LHS, Cmp,
I,
true,
2665 bool IsLogical = isa<SelectInst>(Op0);
2667 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
2669 foldAndOrOfICmps(Cmp,
RHS,
I,
true, IsLogical))
2674 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
2675 if (
Value *Res = foldAndOrOfICmps(Cmp,
RHS,
I,
true,
2683 if (
FCmpInst *
LHS = dyn_cast<FCmpInst>(
I.getOperand(0)))
2684 if (
FCmpInst *
RHS = dyn_cast<FCmpInst>(
I.getOperand(1)))
2685 if (
Value *Res = foldLogicOfFCmps(
LHS,
RHS,
true))
2691 if (
Instruction *CastedAnd = foldCastedBitwiseLogic(
I))
2704 A->getType()->isIntOrIntVectorTy(1))
2710 A->getType()->isIntOrIntVectorTy(1))
2715 A->getType()->isIntOrIntVectorTy(1))
2722 if (
A->getType()->isIntOrIntVectorTy(1))
2735 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2744 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2755 Value *Start =
nullptr, *Step =
nullptr;
2763 return Canonicalized;
2765 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
2777 return BinaryOperator::CreateAnd(V, Op1);
2781 return BinaryOperator::CreateAnd(Op0, V);
2788 bool MatchBitReversals) {
2796 for (
auto *Inst : Insts)
2801std::optional<std::pair<Intrinsic::ID, SmallVector<Value *, 3>>>
2805 assert(
Or.getOpcode() == BinaryOperator::Or &&
"Expecting or instruction");
2807 unsigned Width =
Or.getType()->getScalarSizeInBits();
2812 return std::nullopt;
2819 if (isa<BinaryOperator>(Or0) && isa<BinaryOperator>(Or1)) {
2820 Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
2826 return std::nullopt;
2829 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2835 Or1->
getOpcode() == BinaryOperator::LShr &&
2836 "Illegal or(shift,shift) pair");
2840 auto matchShiftAmount = [&](
Value *L,
Value *R,
unsigned Width) ->
Value * {
2844 if (
LI->ult(Width) && RI->
ult(Width) && (*
LI + *RI) == Width)
2845 return ConstantInt::get(L->getType(), *
LI);
2869 if (ShVal0 != ShVal1)
2880 unsigned Mask = Width - 1;
2904 Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, Width);
2906 ShAmt = matchShiftAmount(ShAmt1, ShAmt0, Width);
2910 return std::nullopt;
2912 FShiftArgs = {ShVal0, ShVal1, ShAmt};
2913 }
else if (isa<ZExtInst>(Or0) || isa<ZExtInst>(Or1)) {
2925 if (!isa<ZExtInst>(Or1))
2929 const APInt *ZextHighShlAmt;
2932 return std::nullopt;
2936 return std::nullopt;
2938 unsigned HighSize =
High->getType()->getScalarSizeInBits();
2939 unsigned LowSize =
Low->getType()->getScalarSizeInBits();
2942 if (ZextHighShlAmt->
ult(LowSize) || ZextHighShlAmt->
ugt(Width - HighSize))
2943 return std::nullopt;
2950 if (!isa<ZExtInst>(
Y))
2953 const APInt *ZextLowShlAmt;
2960 if (*ZextLowShlAmt + *ZextHighShlAmt != Width)
2966 ZextLowShlAmt->
ule(Width - LowSize) &&
"Invalid concat");
2968 FShiftArgs = {U, U, ConstantInt::get(Or0->
getType(), *ZextHighShlAmt)};
2973 if (FShiftArgs.
empty())
2974 return std::nullopt;
2976 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
2977 return std::make_pair(IID, FShiftArgs);
2983 auto [IID, FShiftArgs] = *Opt;
2994 assert(
Or.getOpcode() == Instruction::Or &&
"bswap requires an 'or'");
2995 Value *Op0 =
Or.getOperand(0), *Op1 =
Or.getOperand(1);
2999 if ((Width & 1) != 0)
3001 unsigned HalfWidth = Width / 2;
3004 if (!isa<ZExtInst>(Op0))
3008 Value *LowerSrc, *ShlVal, *UpperSrc;
3021 NewUpper = Builder.
CreateShl(NewUpper, HalfWidth);
3029 Value *LowerBSwap, *UpperBSwap;
3032 return ConcatIntrinsicCalls(Intrinsic::bswap, UpperBSwap, LowerBSwap);
3036 Value *LowerBRev, *UpperBRev;
3039 return ConcatIntrinsicCalls(Intrinsic::bitreverse, UpperBRev, LowerBRev);
3046 unsigned NumElts = cast<FixedVectorType>(C1->
getType())->getNumElements();
3047 for (
unsigned i = 0; i != NumElts; ++i) {
3050 if (!EltC1 || !EltC2)
3069 Type *Ty =
A->getType();
3085 if (
A->getType()->isIntOrIntVectorTy()) {
3087 if (NumSignBits ==
A->getType()->getScalarSizeInBits() &&
3110 Cond->getType()->isIntOrIntVectorTy(1)) {
3136 Cond->getType()->isIntOrIntVectorTy(1) &&
3150 Value *
D,
bool InvertFalseVal) {
3153 Type *OrigType =
A->getType();
3156 if (
Value *
Cond = getSelectCondition(
A,
B, InvertFalseVal)) {
3161 Type *SelTy =
A->getType();
3162 if (
auto *VecTy = dyn_cast<VectorType>(
Cond->getType())) {
3164 unsigned Elts = VecTy->getElementCount().getKnownMinValue();
3185 bool IsAnd,
bool IsLogical,
3192 IsAnd ?
LHS->getInversePredicate() :
LHS->getPredicate();
3194 IsAnd ?
RHS->getInversePredicate() :
RHS->getPredicate();
3203 auto MatchRHSOp = [LHS0, CInt](
const Value *RHSOp) {
3206 (CInt->
isZero() && RHSOp == LHS0);
3237 if (
Value *V = foldAndOrOfICmpsOfAndWithPow2(LHS, RHS, &
I, IsAnd, IsLogical))
3241 Value *LHS0 =
LHS->getOperand(0), *RHS0 =
RHS->getOperand(0);
3242 Value *LHS1 =
LHS->getOperand(1), *RHS1 =
RHS->getOperand(1);
3243 const APInt *LHSC =
nullptr, *RHSC =
nullptr;
3250 if (LHS0 == RHS1 && LHS1 == RHS0) {
3254 if (LHS0 == RHS0 && LHS1 == RHS1) {
3257 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
3306 if (IsAnd && !IsLogical)
3324 if (
Value *
X = foldEqOfParts(LHS, RHS, IsAnd))
3359 const APInt *AndC, *SmallC =
nullptr, *BigC =
nullptr;
3373 if (SmallC && BigC) {
3374 unsigned BigBitSize = BigC->getBitWidth();
3393 bool TrueIfSignedL, TrueIfSignedR;
3399 if ((TrueIfSignedL && !TrueIfSignedR &&
3402 (!TrueIfSignedL && TrueIfSignedR &&
3409 if ((TrueIfSignedL && !TrueIfSignedR &&
3412 (!TrueIfSignedL && TrueIfSignedR &&
3421 return foldAndOrOfICmpsUsingRanges(LHS, RHS, IsAnd);
3457 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
3458 Type *Ty =
I.getType();
3460 if (
auto *SI0 = dyn_cast<SelectInst>(Op0)) {
3462 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
false))
3465 if (
auto *SI1 = dyn_cast<SelectInst>(Op1)) {
3467 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
false))
3498 return BinaryOperator::CreateXor(
Or, ConstantInt::get(Ty, *CV));
3506 return BinaryOperator::CreateMul(
X, IncrementY);
3515 const APInt *C0, *C1;
3534 if ((*C0 & *C1).
isZero()) {
3539 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
3540 return BinaryOperator::CreateAnd(
A, C01);
3546 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
3547 return BinaryOperator::CreateAnd(
B, C01);
3551 const APInt *C2, *C3;
3556 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
3557 return BinaryOperator::CreateAnd(
Or, C01);
3567 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D))
3569 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B))
3571 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D))
3573 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B))
3575 if (
Value *V = matchSelectFromAndOr(
B,
D,
A,
C))
3577 if (
Value *V = matchSelectFromAndOr(
B,
D,
C,
A))
3579 if (
Value *V = matchSelectFromAndOr(
D,
B,
A,
C))
3581 if (
Value *V = matchSelectFromAndOr(
D,
B,
C,
A))
3590 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D,
true))
3592 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B,
true))
3594 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D,
true))
3596 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B,
true))
3603 return BinaryOperator::CreateOr(Op0,
C);
3608 return BinaryOperator::CreateOr(Op1,
C);
3614 bool SwappedForXor =
false;
3617 SwappedForXor =
true;
3624 return BinaryOperator::CreateOr(Op0,
B);
3626 return BinaryOperator::CreateOr(Op0,
A);
3632 return BinaryOperator::CreateOr(
A,
B);
3660 return BinaryOperator::CreateOr(Nand,
C);
3678 bool IsLogical = isa<SelectInst>(Op1);
3680 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
3682 foldAndOrOfICmps(
LHS, Cmp,
I,
false, IsLogical))
3687 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
3688 if (
Value *Res = foldAndOrOfICmps(
LHS, Cmp,
I,
false,
3695 bool IsLogical = isa<SelectInst>(Op0);
3697 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
3699 foldAndOrOfICmps(Cmp,
RHS,
I,
false, IsLogical))
3704 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
3705 if (
Value *Res = foldAndOrOfICmps(Cmp,
RHS,
I,
false,
3713 if (
FCmpInst *
LHS = dyn_cast<FCmpInst>(
I.getOperand(0)))
3714 if (
FCmpInst *
RHS = dyn_cast<FCmpInst>(
I.getOperand(1)))
3715 if (
Value *Res = foldLogicOfFCmps(
LHS,
RHS,
false))
3733 A->getType()->isIntOrIntVectorTy(1))
3746 return BinaryOperator::CreateOr(Inner, CI);
3753 Value *
X =
nullptr, *
Y =
nullptr;
3785 return BinaryOperator::CreateXor(
A,
B);
3801 Value *
Mul, *Ov, *MulIsNotZero, *UMulWithOv;
3818 if (
match(UMulWithOv, m_Intrinsic<Intrinsic::umul_with_overflow>(
3822 return BinaryOperator::CreateAnd(NotNullA, NotNullB);
3831 const APInt *C1, *C2;
3847 : C2->
uadd_ov(*C1, Overflow));
3851 return BinaryOperator::CreateOr(Ov, NewCmp);
3871 Value *Start =
nullptr, *Step =
nullptr;
3889 return BinaryOperator::CreateOr(
3901 return BinaryOperator::CreateOr(
3909 return Canonicalized;
3911 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
3932 Attribute::NoImplicitFloat)) {
3945 if ((KnownX.
One & *C2) == *C2)
3946 return BinaryOperator::CreateAnd(
X, ConstantInt::get(Ty, *C1 | *C2));
3955 return BinaryOperator::CreateOr(V, Op1);
3959 return BinaryOperator::CreateOr(Op0, V);
3968 assert(
I.getOpcode() == Instruction::Xor);
3969 Value *Op0 =
I.getOperand(0);
3970 Value *Op1 =
I.getOperand(1);
3981 return BinaryOperator::CreateXor(
A,
B);
3989 return BinaryOperator::CreateXor(
A,
B);
3997 return BinaryOperator::CreateXor(
A,
B);
4019 assert(
I.getOpcode() == Instruction::Xor &&
I.getOperand(0) == LHS &&
4020 I.getOperand(1) == RHS &&
"Should be 'xor' with these operands");
4023 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
4024 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
4027 if (LHS0 == RHS1 && LHS1 == RHS0) {
4031 if (LHS0 == RHS0 && LHS1 == RHS1) {
4034 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
4042 const APInt *LC, *RC;
4051 bool TrueIfSignedL, TrueIfSignedR;
4067 if (CRUnion && CRIntersect)
4068 if (
auto CR = CRUnion->exactIntersectWith(CRIntersect->inverse())) {
4069 if (CR->isFullSet())
4071 if (CR->isEmptySet())
4076 CR->getEquivalentICmp(NewPred, NewC,
Offset);
4085 ConstantInt::get(Ty, NewC));
4103 if (OrICmp == LHS && AndICmp == RHS) {
4108 if (OrICmp == RHS && AndICmp == LHS) {
4115 Y->setPredicate(
Y->getInversePredicate());
4117 if (!
Y->hasOneUse()) {
4128 Y->replaceUsesWithIf(NotY,
4129 [NotY](
Use &U) {
return U.getUser() != NotY; });
4169 return BinaryOperator::CreateXor(NewA,
X);
4175 Type *EltTy =
C->getType()->getScalarType();
4181 return BinaryOperator::CreateOr(
LHS,
RHS);
4196 return A ==
C ||
A ==
D ||
B ==
C ||
B ==
D;
4205 return BinaryOperator::CreateOr(
X, NotY);
4213 return BinaryOperator::CreateOr(
Y, NotX);
4223 assert(
Xor.getOpcode() == Instruction::Xor &&
"Expected an xor instruction.");
4229 Value *Op0 =
Xor.getOperand(0), *Op1 =
Xor.getOperand(1);
4244 auto *
Add = cast<BinaryOperator>(Op0);
4245 Value *NegA =
Add->hasNoUnsignedWrap()
4255 auto *
I = dyn_cast<Instruction>(
Op);
4262 auto *
I = cast<Instruction>(
Op);
4265 Op->replaceUsesWithIf(NotOp,
4266 [NotOp](
Use &U) {
return U.getUser() != NotOp; });
4288 bool IsBinaryOp = isa<BinaryOperator>(
I);
4328 bool IsBinaryOp = isa<BinaryOperator>(
I);
4330 Value *NotOp0 =
nullptr;
4331 Value *NotOp1 =
nullptr;
4332 Value **OpToInvert =
nullptr;
4377 Type *Ty =
I.getType();
4381 return BinaryOperator::CreateOr(
X, NotY);
4392 return BinaryOperator::CreateAnd(
X, NotY);
4407 return BinaryOperator::CreateAnd(DecX, NotY);
4412 return BinaryOperator::CreateAShr(
X,
Y);
4418 return BinaryOperator::CreateAShr(
X,
Y);
4474 Type *SextTy = cast<BitCastOperator>(NotOp)->getSrcTy();
4480 if (
auto *NotOpI = dyn_cast<Instruction>(NotOp))
4487 auto *II = dyn_cast<IntrinsicInst>(NotOp);
4488 if (II && II->hasOneUse()) {
4496 if (II->getIntrinsicID() == Intrinsic::is_fpclass) {
4497 ConstantInt *ClassMask = cast<ConstantInt>(II->getArgOperand(1));
4499 1, ConstantInt::get(ClassMask->
getType(),
4514 if (
auto *Sel = dyn_cast<SelectInst>(NotOp)) {
4515 Value *TV = Sel->getTrueValue();
4516 Value *FV = Sel->getFalseValue();
4517 auto *CmpT = dyn_cast<CmpInst>(TV);
4518 auto *CmpF = dyn_cast<CmpInst>(FV);
4519 bool InvertibleT = (CmpT && CmpT->hasOneUse()) || isa<Constant>(TV);
4520 bool InvertibleF = (CmpF && CmpF->hasOneUse()) || isa<Constant>(FV);
4521 if (InvertibleT && InvertibleF) {
4523 CmpT->setPredicate(CmpT->getInversePredicate());
4527 CmpF->setPredicate(CmpF->getInversePredicate());
4585 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
4589 return BinaryOperator::CreateDisjointOr(Op0, Op1);
4606 return BinaryOperator::CreateXor(
4629 *CA ==
X->getType()->getScalarSizeInBits() - 1 &&
4637 Type *Ty =
I.getType();
4645 return BinaryOperator::CreateSub(ConstantInt::get(Ty, *
C + *RHSC),
X);
4649 return BinaryOperator::CreateAdd(
X, ConstantInt::get(Ty, *
C + *RHSC));
4654 return BinaryOperator::CreateXor(
X, ConstantInt::get(Ty, *
C ^ *RHSC));
4659 auto *II = dyn_cast<IntrinsicInst>(Op0);
4662 if ((IID == Intrinsic::ctlz || IID == Intrinsic::cttz) &&
4665 IID = (IID == Intrinsic::ctlz) ? Intrinsic::cttz : Intrinsic::ctlz;
4677 return BinaryOperator::CreateShl(NotX, ConstantInt::get(Ty, *
C));
4683 return BinaryOperator::CreateLShr(NotX, ConstantInt::get(Ty, *
C));
4702 Attribute::NoImplicitFloat)) {
4726 return BinaryOperator::CreateXor(Opnd0, ConstantInt::get(Ty, FoldConst));
4759 return BinaryOperator::CreateXor(
4765 return BinaryOperator::CreateXor(
4771 return BinaryOperator::CreateOr(
A,
B);
4775 return BinaryOperator::CreateOr(
A,
B);
4785 return BinaryOperator::CreateOr(
A,
B);
4800 if (
B ==
C ||
B ==
D)
4811 if (
I.getType()->isIntOrIntVectorTy(1) &&
4814 bool NeedFreeze = isa<SelectInst>(Op0) && isa<SelectInst>(Op1) &&
B ==
D;
4815 if (
B ==
C ||
B ==
D)
4827 if (
auto *
LHS = dyn_cast<ICmpInst>(
I.getOperand(0)))
4828 if (
auto *
RHS = dyn_cast<ICmpInst>(
I.getOperand(1)))
4832 if (
Instruction *CastedXor = foldCastedBitwiseLogic(
I))
4852 return Canonicalized;
4854 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
4857 if (
Instruction *Folded = canonicalizeConditionalNegationViaMathToSelect(
I))
amdgpu AMDGPU Register Bank Select
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static bool isSigned(unsigned int Opcode)
static unsigned conjugateICmpMask(unsigned Mask)
Convert an analysis of a masked ICmp into its equivalent if all boolean operations had the opposite s...
static Instruction * foldNotXor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static bool matchIsFPClassLikeFCmp(Value *Op, Value *&ClassVal, uint64_t &ClassMask)
Match an fcmp against a special value that performs a test possible by llvm.is.fpclass.
static Value * foldSignedTruncationCheck(ICmpInst *ICmp0, ICmpInst *ICmp1, Instruction &CxtI, InstCombiner::BuilderTy &Builder)
General pattern: X & Y.
static Instruction * visitMaskedMerge(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
If we have a masked merge, in the canonical form of: (assuming that A only has one use....
static Instruction * canonicalizeAbs(BinaryOperator &Xor, InstCombiner::BuilderTy &Builder)
Canonicalize a shifty way to code absolute value to the more common pattern that uses negation and se...
static Value * foldUnsignedUnderflowCheck(ICmpInst *ZeroICmp, ICmpInst *UnsignedICmp, bool IsAnd, const SimplifyQuery &Q, InstCombiner::BuilderTy &Builder)
Commuted variants are assumed to be handled by calling this function again with the parameters swappe...
static Instruction * foldOrToXor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static Value * simplifyAndOrWithOpReplaced(Value *V, Value *Op, Value *RepOp, bool SimplifyOnly, InstCombinerImpl &IC, unsigned Depth=0)
static Instruction * matchDeMorgansLaws(BinaryOperator &I, InstCombiner &IC)
Match variations of De Morgan's Laws: (~A & ~B) == (~(A | B)) (~A | ~B) == (~(A & B))
static Value * foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, Value *A, Value *B, Value *C, Value *D, Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR, InstCombiner::BuilderTy &Builder)
Try to fold (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E) into a single (icmp(A & X) ==/!...
static Value * foldIsPowerOf2OrZero(ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd, InstCombiner::BuilderTy &Builder)
Fold (icmp eq ctpop(X) 1) | (icmp eq X 0) into (icmp ult ctpop(X) 2) and fold (icmp ne ctpop(X) 1) & ...
static Instruction * foldAndToXor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static unsigned getMaskedICmpType(Value *A, Value *B, Value *C, ICmpInst::Predicate Pred)
Return the set of patterns (from MaskedICmpType) that (icmp SCC (A & B), C) satisfies.
static Instruction * foldXorToXor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
A ^ B can be specified using other logic ops in a variety of patterns.
static bool canNarrowShiftAmt(Constant *C, unsigned BitWidth)
Return true if a constant shift amount is always less than the specified bit-width.
static Instruction * foldLogicCastConstant(BinaryOperator &Logic, CastInst *Cast, InstCombinerImpl &IC)
Fold {and,or,xor} (cast X), C.
static Value * foldAndOrOfICmpEqConstantAndICmp(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, bool IsLogical, IRBuilderBase &Builder)
static bool canFreelyInvert(InstCombiner &IC, Value *Op, Instruction *IgnoredUser)
static Value * foldNegativePower2AndShiftedMask(Value *A, Value *B, Value *D, Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR, InstCombiner::BuilderTy &Builder)
Try to fold (icmp(A & B) == 0) & (icmp(A & D) != E) into (icmp A u< D) iff B is a contiguous set of o...
static Value * matchIsFiniteTest(InstCombiner::BuilderTy &Builder, FCmpInst *LHS, FCmpInst *RHS)
and (fcmp ord x, 0), (fcmp u* x, inf) -> fcmp o* x, inf
static Value * foldPowerOf2AndShiftedMask(ICmpInst *Cmp0, ICmpInst *Cmp1, bool JoinedByAnd, InstCombiner::BuilderTy &Builder)
Try to fold ((icmp X u< P) & (icmp(X & M) != M)) or ((icmp X s> -1) & (icmp(X & M) !...
static Value * stripSignOnlyFPOps(Value *Val)
Ignore all operations which only change the sign of a value, returning the underlying magnitude value...
static Value * freelyInvert(InstCombinerImpl &IC, Value *Op, Instruction *IgnoredUser)
static Value * foldLogOpOfMaskedICmps(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, bool IsLogical, InstCombiner::BuilderTy &Builder)
Try to fold (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E) into a single (icmp(A & X) ==/!...
static Value * foldIsPowerOf2(ICmpInst *Cmp0, ICmpInst *Cmp1, bool JoinedByAnd, InstCombiner::BuilderTy &Builder)
Reduce a pair of compares that check if a value has exactly 1 bit set.
static Value * foldLogOpOfMaskedICmpsAsymmetric(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, Value *A, Value *B, Value *C, Value *D, Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR, unsigned LHSMask, unsigned RHSMask, InstCombiner::BuilderTy &Builder)
Try to fold (icmp(A & B) ==/!= 0) &/| (icmp(A & D) ==/!= E) into a single (icmp(A & X) ==/!...
static std::optional< IntPart > matchIntPart(Value *V)
Match an extraction of bits from an integer.
static Instruction * canonicalizeLogicFirst(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static Instruction * reassociateFCmps(BinaryOperator &BO, InstCombiner::BuilderTy &Builder)
This a limited reassociation for a special case (see above) where we are checking if two values are e...
static Value * getNewICmpValue(unsigned Code, bool Sign, Value *LHS, Value *RHS, InstCombiner::BuilderTy &Builder)
This is the complement of getICmpCode, which turns an opcode and two operands into either a constant ...
static std::optional< std::pair< unsigned, unsigned > > getMaskedTypeForICmpPair(Value *&A, Value *&B, Value *&C, Value *&D, Value *&E, ICmpInst *LHS, ICmpInst *RHS, ICmpInst::Predicate &PredL, ICmpInst::Predicate &PredR)
Handle (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E).
static Value * extractIntPart(const IntPart &P, IRBuilderBase &Builder)
Materialize an extraction of bits from an integer in IR.
static bool matchUnorderedInfCompare(FCmpInst::Predicate P, Value *LHS, Value *RHS)
Matches fcmp u__ x, +/-inf.
static Instruction * matchOrConcat(Instruction &Or, InstCombiner::BuilderTy &Builder)
Attempt to combine or(zext(x),shl(zext(y),bw/2) concat packing patterns.
static bool matchIsNotNaN(FCmpInst::Predicate P, Value *LHS, Value *RHS)
Matches canonical form of isnan, fcmp ord x, 0.
static bool areInverseVectorBitmasks(Constant *C1, Constant *C2)
If all elements of two constant vectors are 0/-1 and inverses, return true.
MaskedICmpType
Classify (icmp eq (A & B), C) and (icmp ne (A & B), C) as matching patterns that can be simplified.
static Instruction * foldComplexAndOrPatterns(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
Try folding relatively complex patterns for both And and Or operations with all And and Or swapped.
static Value * getFCmpValue(unsigned Code, Value *LHS, Value *RHS, InstCombiner::BuilderTy &Builder)
This is the complement of getFCmpCode, which turns an opcode and two operands into either a FCmp inst...
static Instruction * matchFunnelShift(Instruction &Or, InstCombinerImpl &IC)
Match UB-safe variants of the funnel shift intrinsic.
static Instruction * reassociateForUses(BinaryOperator &BO, InstCombinerImpl::BuilderTy &Builder)
Try to reassociate a pair of binops so that values with one use only are part of the same instruction...
static Instruction * foldBitwiseLogicWithIntrinsics(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static Value * foldAndOrOfICmpsWithConstEq(ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd, bool IsLogical, InstCombiner::BuilderTy &Builder, const SimplifyQuery &Q)
Reduce logic-of-compares with equality to a constant by substituting a common operand with the consta...
This file provides internal interfaces used to implement the InstCombine.
This file provides the interface for the instcombine pass implementation.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static constexpr int Concat[]
support::ulittle16_t & Lo
support::ulittle16_t & Hi
bool bitwiseIsEqual(const APFloat &RHS) const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
APInt trunc(unsigned width) const
Truncate to new width.
unsigned countLeadingOnes() const
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
APInt usub_ov(const APInt &RHS, bool &Overflow) const
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isSignMask() const
Check if the APInt's value is returned by getSignMask.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
APInt sadd_ov(const APInt &RHS, bool &Overflow) const
bool intersects(const APInt &RHS) const
This operation tests if there are any pairs of corresponding bits between this APInt and RHS that are...
int32_t exactLogBase2() const
APInt reverseBits() const
APInt uadd_ov(const APInt &RHS, bool &Overflow) const
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countLeadingZeros() const
bool ule(const APInt &RHS) const
Unsigned less or equal comparison.
APInt shl(unsigned shiftAmt) const
Left-shift function.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
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.
APInt ssub_ov(const APInt &RHS, bool &Overflow) const
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
const Function * getParent() const
Return the enclosing method, or null if none.
bool isSigned() const
Whether the intrinsic is signed or unsigned.
Instruction::BinaryOps getBinaryOp() const
Returns the binary operation underlying the intrinsic.
static BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name, BasicBlock::iterator InsertBefore)
Construct a binary instruction, given the opcode and the two operands.
BinaryOps getOpcode() const
static BinaryOperator * CreateNot(Value *Op, const Twine &Name, BasicBlock::iterator InsertBefore)
static BinaryOperator * CreateWithCopiedFlags(BinaryOps Opc, Value *V1, Value *V2, Value *CopyO, const Twine &Name, BasicBlock::iterator InsertBefore)
This class represents a no-op cast from one type to another.
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr, BasicBlock::iterator InsertBefore)
This is the base class for all instructions that perform data casts.
Type * getSrcTy() const
Return the source type, as a convenience.
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
static CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name, BasicBlock::iterator InsertBefore)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
static CastInst * CreateBitOrPointerCast(Value *S, Type *Ty, const Twine &Name, BasicBlock::iterator InsertBefore)
Create a BitCast, a PtrToInt, or an IntToPTr cast instruction.
Type * getDestTy() const
Return the destination type, as a convenience.
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ 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
@ 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
@ ICMP_ULT
unsigned less 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
@ ICMP_ULE
unsigned less or equal
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Predicate getOrderedPredicate() const
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 isUnordered(Predicate predicate)
Determine if the predicate is an unordered operation.
static Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getNot(Constant *C)
static Constant * getXor(Constant *C1, Constant *C2)
static Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getExactLogBase2(Constant *C)
If C is a scalar/fixed width vector of known powers of 2, then this function returns a new scalar/fix...
static Constant * getCompare(unsigned short pred, Constant *C1, Constant *C2, bool OnlyIfReduced=false)
Return an ICmp or FCmp comparison operator constant expression.
This is the shared class of boolean and integer constants.
bool isMinusOne() const
This function will return true iff every bit in this constant is set to true.
static ConstantInt * getTrue(LLVMContext &Context)
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static ConstantInt * getFalse(LLVMContext &Context)
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
const APInt & getValue() const
Return the constant as an APInt value reference.
This class represents a range of values.
std::optional< ConstantRange > exactUnionWith(const ConstantRange &CR) const
Union the two ranges and return the result if it can be represented exactly, otherwise return std::nu...
ConstantRange subtract(const APInt &CI) const
Subtract the specified constant from the endpoints of this constant range.
const APInt & getLower() const
Return the lower value for this range.
bool isWrappedSet() const
Return true if this set wraps around the unsigned domain.
const APInt & getUpper() const
Return the upper value for this range.
static ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)
Produce the exact range such that all values in the returned range satisfy the given predicate with a...
std::optional< ConstantRange > exactIntersectWith(const ConstantRange &CR) const
Intersect the two ranges and return the result if it can be represented exactly, otherwise return std...
This is an important base class in LLVM.
static Constant * replaceUndefsWith(Constant *C, Constant *Replacement)
Try to replace undefined constant C or undefined elements in C with Replacement.
static Constant * mergeUndefsWith(Constant *C, Constant *Other)
Merges undefs of a Constant with another Constant, along with the undefs already present.
static Constant * getAllOnesValue(Type *Ty)
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
bool isZeroValue() const
Return true if the value is negative zero or null value.
This class represents an Operation in the Expression.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
This instruction compares its operands according to the predicate given to the constructor.
Convenience struct for specifying and reasoning about fast-math flags.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
This instruction compares its operands according to the predicate given to the constructor.
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.
Common base class shared among various IRBuilders.
CallInst * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with 1 operand which is mangled on its type.
Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with 2 operands which is mangled on the first type.
Value * CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateLogicalOp(Instruction::BinaryOps Opc, Value *Cond1, Value *Cond2, const Twine &Name="")
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
Value * CreateICmpSGT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
ConstantInt * getTrue()
Get the constant value for i1 true.
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateFreeze(Value *V, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateIsNotNeg(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg > -1.
BasicBlock * GetInsertBlock() const
void setFastMathFlags(FastMathFlags NewFMF)
Set the fast-math flags to be used with generated fp-math operators.
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateIsNeg(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg < 0.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateICmpUGT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateLogicalAnd(Value *Cond1, Value *Cond2, const Twine &Name="")
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="")
Value * CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateIsNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg == 0.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateLogicalOr(Value *Cond1, Value *Cond2, const Twine &Name="")
Value * CreateFNeg(Value *V, const Twine &Name="", MDNode *FPMathTag=nullptr)
Instruction * canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(BinaryOperator &I)
Instruction * foldBinOpIntoSelectOrPhi(BinaryOperator &I)
This is a convenience wrapper function for the above two functions.
Instruction * visitOr(BinaryOperator &I)
bool SimplifyAssociativeOrCommutative(BinaryOperator &I)
Performs a few simplifications for operators which are associative or commutative.
Value * foldUsingDistributiveLaws(BinaryOperator &I)
Tries to simplify binary operations which some other binary operation distributes over.
Instruction * foldBinOpShiftWithShift(BinaryOperator &I)
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).
bool sinkNotIntoLogicalOp(Instruction &I)
std::optional< std::pair< Intrinsic::ID, SmallVector< Value *, 3 > > > convertOrOfShiftsToFunnelShift(Instruction &Or)
Constant * getLosslessUnsignedTrunc(Constant *C, Type *TruncTy)
Instruction * visitAnd(BinaryOperator &I)
bool sinkNotIntoOtherHandOfLogicalOp(Instruction &I)
Instruction * foldBinopWithPhiOperands(BinaryOperator &BO)
For a binary operator with 2 phi operands, try to hoist the binary operation before the phi.
Value * simplifyRangeCheck(ICmpInst *Cmp0, ICmpInst *Cmp1, bool Inverted)
Try to fold a signed range checked with lower bound 0 to an unsigned icmp.
Instruction * tryFoldInstWithCtpopWithNot(Instruction *I)
Constant * getLosslessSignedTrunc(Constant *C, Type *TruncTy)
Instruction * visitXor(BinaryOperator &I)
bool SimplifyDemandedInstructionBits(Instruction &Inst)
Tries to simplify operands to an integer instruction based on its demanded bits.
Instruction * foldVectorBinop(BinaryOperator &Inst)
Canonicalize the position of binops relative to shufflevector.
Instruction * matchBSwapOrBitReverse(Instruction &I, bool MatchBSwaps, bool MatchBitReversals)
Given an initial instruction, check to see if it is the root of a bswap/bitreverse idiom.
void freelyInvertAllUsersOf(Value *V, Value *IgnoredUser=nullptr)
Freely adapt every user of V as-if V was changed to !V.
The core instruction combiner logic.
bool isFreeToInvert(Value *V, bool WillInvertAllUses, bool &DoesConsume)
Return true if the specified value is free to invert (apply ~ to).
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, unsigned Depth=0, const Instruction *CxtI=nullptr)
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
InstructionWorklist & Worklist
A worklist of the instructions that need to be simplified.
unsigned ComputeNumSignBits(const Value *Op, unsigned Depth=0, const Instruction *CxtI=nullptr) const
static Value * peekThroughBitcast(Value *V, bool OneUseOnly=false)
Return the source operand of a potentially bitcasted value while optionally checking if it has one us...
bool canFreelyInvertAllUsersOf(Instruction *V, Value *IgnoredUser)
Given i1 V, can every user of V be freely adapted if V is changed to !V ? InstCombine's freelyInvertA...
void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth, const Instruction *CxtI) const
bool MaskedValueIsZero(const Value *V, const APInt &Mask, unsigned Depth=0, const Instruction *CxtI=nullptr) const
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
const SimplifyQuery & getSimplifyQuery() const
void pushUsersToWorkList(Instruction &I)
When an instruction is simplified, add all users of the instruction to the work lists because they mi...
void push(Instruction *I)
Push the instruction onto the worklist stack.
void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
A wrapper class for inspecting calls to intrinsic functions.
This class represents a sign extension of integer types.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr, BasicBlock::iterator InsertBefore, Instruction *MDFrom=nullptr)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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.
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isIEEE() const
Return whether the type is IEEE compatible, as defined by the eponymous method in APFloat.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) 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.
iterator_range< user_iterator > users()
bool hasNUsesOrMore(unsigned N) const
Return true if this value has N uses or more.
bool hasNUses(unsigned N) const
Return true if this Value has exactly N uses.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
static VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
Represents an op.with.overflow intrinsic.
This class represents zero extension of integer types.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const APInt & umin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be unsigned.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
cst_pred_ty< is_lowbit_mask > m_LowBitMask()
Match an integer or vector with only the low bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
cst_pred_ty< is_negative > m_Negative()
Match an integer or vector of negative values.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
cst_pred_ty< is_sign_mask > m_SignMask()
Match an integer or vector with only the sign bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
cstfp_pred_ty< is_inf > m_Inf()
Match a positive or negative infinity FP constant.
m_Intrinsic_Ty< Opnd0 >::Ty m_BitReverse(const Opnd0 &Op0)
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power-of-2.
auto m_LogicalOp()
Matches either L && R or L || R where L and R are arbitrary values.
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWSub(const LHS &L, const RHS &R)
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
match_combine_or< CastInst_match< OpTy, ZExtInst >, OpTy > m_ZExtOrSelf(const OpTy &Op)
bool match(Val *V, const Pattern &P)
cst_pred_ty< is_shifted_mask > m_ShiftedMask()
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
constantexpr_match m_ConstantExpr()
Match a constant expression or a constant that contains a constant expression.
specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)
cst_pred_ty< is_nonnegative > m_NonNegative()
Match an integer or vector of non-negative values.
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
match_combine_or< CastInst_match< OpTy, SExtInst >, OpTy > m_SExtOrSelf(const OpTy &Op)
BinOpPred_match< LHS, RHS, is_logical_shift_op > m_LogicalShift(const LHS &L, const RHS &R)
Matches logical shift operations.
match_combine_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)
Combine two pattern matchers matching L && R.
CmpClass_match< LHS, RHS, FCmpInst, FCmpInst::Predicate > m_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R)
CastOperator_match< OpTy, Instruction::Trunc > m_Trunc(const OpTy &Op)
Matches Trunc.
bind_ty< WithOverflowInst > m_WithOverflowInst(WithOverflowInst *&I)
Match a with overflow intrinsic, capturing it if we match.
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::Mul > m_Mul(const LHS &L, const RHS &R)
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
cst_pred_ty< is_zero_int > m_ZeroInt()
Match an integer 0 or a vector with all elements equal to 0.
apint_match m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate > m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)
OneUse_match< T > m_OneUse(const T &SubPattern)
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
BinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub > m_Neg(const ValTy &V)
Matches a 'Neg' as 'sub 0, V'.
match_combine_and< class_match< Constant >, match_unless< constantexpr_match > > m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
cst_pred_ty< is_negated_power2 > m_NegatedPower2()
Match a integer or vector negated power-of-2.
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate, true > m_c_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
DisjointOr_match< LHS, RHS, true > m_c_DisjointOr(const LHS &L, const RHS &R)
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.
apfloat_match m_APFloatAllowPoison(const APFloat *&Res)
Match APFloat while allowing poison in splat vector constants.
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".
CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
match_combine_or< match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty, true >, MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty, true > >, match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty, true >, MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty, true > > > m_c_MaxOrMin(const LHS &L, const RHS &R)
match_combine_or< CastOperator_match< OpTy, Instruction::Trunc >, OpTy > m_TruncOrSelf(const OpTy &Op)
match_combine_or< CastInst_match< OpTy, SExtInst >, NNegZExt_match< OpTy > > m_SExtLike(const OpTy &Op)
Match either "sext" or "zext nneg".
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
cst_pred_ty< is_maxsignedvalue > m_MaxSignedValue()
Match an integer or vector with values having all bits except for the high bit set (0x7f....
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
AnyBinaryOp_match< LHS, RHS, true > m_c_BinOp(const LHS &L, const RHS &R)
Matches a BinaryOperator with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > > m_ZExtOrSExt(const OpTy &Op)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
BinOpPred_match< LHS, RHS, is_shift_op > m_Shift(const LHS &L, const RHS &R)
Matches shift operations.
cstfp_pred_ty< is_pos_zero_fp > m_PosZeroFP()
Match a floating-point positive zero.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
BinaryOp_match< cst_pred_ty< is_all_ones >, ValTy, Instruction::Xor, true > m_Not(const ValTy &V)
Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
m_Intrinsic_Ty< Opnd0 >::Ty m_BSwap(const Opnd0 &Op0)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
ElementWiseBitCast_match< OpTy > m_ElementWiseBitCast(const OpTy &Op)
m_Intrinsic_Ty< Opnd0 >::Ty m_FAbs(const Opnd0 &Op0)
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_CopySign(const Opnd0 &Op0, const Opnd1 &Op1)
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
match_unless< Ty > m_Unless(const Ty &M)
Match if the inner matcher does NOT match.
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
cst_pred_ty< icmp_pred_with_threshold > m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold)
Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.
NodeAddr< CodeNode * > Code
This is an optimization pass for GlobalISel generic memory operations.
Intrinsic::ID getInverseMinMaxIntrinsic(Intrinsic::ID MinMaxID)
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
Constant * getPredForFCmpCode(unsigned Code, Type *OpTy, CmpInst::Predicate &Pred)
This is the complement of getFCmpCode.
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.
bool predicatesFoldable(CmpInst::Predicate P1, CmpInst::Predicate P2)
Return true if both predicates match sign or if at least one of them is an equality comparison (which...
Value * simplifyOrInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an Or, fold the result or return null.
Value * simplifyXorInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an Xor, fold the result or return null.
bool matchSimpleRecurrence(const PHINode *P, BinaryOperator *&BO, Value *&Start, Value *&Step)
Attempt to match a simple first order recurrence cycle of the form: iv = phi Ty [Start,...
bool recognizeBSwapOrBitReverseIdiom(Instruction *I, bool MatchBSwaps, bool MatchBitReversals, SmallVectorImpl< Instruction * > &InsertedInsts)
Try to match a bswap or bitreverse idiom.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Value * simplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an And, fold the result or return null.
Value * simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an ICmpInst, fold the result or return null.
bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
bool isKnownNegative(const Value *V, const SimplifyQuery &DL, unsigned Depth=0)
Returns true if the given value is known be negative (i.e.
@ Or
Bitwise or logical OR of integers.
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
constexpr unsigned BitWidth
std::pair< Value *, FPClassTest > fcmpToClassTest(CmpInst::Predicate Pred, const Function &F, Value *LHS, Value *RHS, bool LookThroughSrc=true)
Returns a pair of values, which if passed to llvm.is.fpclass, returns the same result as an fcmp with...
APFloat neg(APFloat X)
Returns the negated value of the argument.
bool decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate &Pred, Value *&X, APInt &Mask, bool LookThroughTrunc=true)
Decompose an icmp into the form ((X & Mask) pred 0) if possible.
unsigned getICmpCode(CmpInst::Predicate Pred)
Encode a icmp predicate into a three bit mask.
unsigned getFCmpCode(CmpInst::Predicate CC)
Similar to getICmpCode but for FCmpInst.
Constant * getPredForICmpCode(unsigned Code, bool Sign, Type *OpTy, CmpInst::Predicate &Pred)
This is the complement of getICmpCode.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isNonNegative() const
Returns true if this value is known to be non-negative.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
SimplifyQuery getWithInstruction(const Instruction *I) const