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)) {
185 LHS,
RHS, Pred,
true,
true);
191 Y = ConstantInt::get(
X->getType(), Res->Mask);
192 Z = ConstantInt::get(
X->getType(), Res->C);
217 Value *L11, *L12, *L21, *L22;
220 L21 = L22 = L1 =
nullptr;
245 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
248 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
265 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
270 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
293 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
298 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
307 assert(Ok &&
"Failed to find AND on the right side of the RHS icmp.");
313 }
else if (L12 ==
A) {
316 }
else if (L21 ==
A) {
319 }
else if (L22 ==
A) {
326 return std::optional<std::pair<unsigned, unsigned>>(
327 std::make_pair(LeftType, RightType));
349 const APInt *BCst, *DCst, *OrigECst;
360 APInt ECst = *OrigECst;
366 if (*BCst == 0 || *DCst == 0)
377 Attribute::StrictFP)) {
378 Type *Ty = Src->getType()->getScalarType();
385 APInt FractionBits = ~ExpBits;
387 if (*BCst != FractionBits)
412 if ((((*BCst & *DCst) & ECst) == 0) &&
413 (*BCst & (*BCst ^ *DCst)).isPowerOf2()) {
414 APInt BorD = *BCst | *DCst;
415 APInt BandBxorDorE = (*BCst & (*BCst ^ *DCst)) | ECst;
416 Value *NewMask = ConstantInt::get(
A->getType(), BorD);
417 Value *NewMaskedValue = ConstantInt::get(
A->getType(), BandBxorDorE);
419 return Builder.
CreateICmp(NewCC, NewAnd, NewMaskedValue);
422 auto IsSubSetOrEqual = [](
const APInt *C1,
const APInt *C2) {
423 return (*C1 & *C2) == *C1;
425 auto IsSuperSetOrEqual = [](
const APInt *C1,
const APInt *C2) {
426 return (*C1 & *C2) == *C2;
435 if (!IsSubSetOrEqual(BCst, DCst) && !IsSuperSetOrEqual(BCst, DCst))
447 if (IsSubSetOrEqual(BCst, DCst))
448 return ConstantInt::get(
LHS->
getType(), !IsAnd);
458 if (IsSuperSetOrEqual(BCst, DCst)) {
460 RHS->setSameSign(
false);
466 assert(IsSubSetOrEqual(BCst, DCst) &&
"Precondition due to above code");
467 if ((*BCst & ECst) != 0) {
469 RHS->setSameSign(
false);
476 return ConstantInt::get(
LHS->
getType(), !IsAnd);
488 "Expected equality predicates for masked type of icmps.");
500 LHS,
RHS, IsAnd,
A,
B,
D, E, PredL, PredR, Builder)) {
505 RHS,
LHS, IsAnd,
A,
D,
B,
C, PredR, PredL, Builder)) {
517 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *E =
nullptr;
519 std::optional<std::pair<unsigned, unsigned>> MaskPair =
524 "Expected equality predicates for masked type of icmps.");
525 unsigned LHSMask = MaskPair->first;
526 unsigned RHSMask = MaskPair->second;
527 unsigned Mask = LHSMask & RHSMask;
532 LHS,
RHS, IsAnd,
A,
B,
C,
D, E, PredL, PredR, LHSMask, RHSMask,
568 return Builder.
CreateICmp(NewCC, NewAnd, Zero);
577 return Builder.
CreateICmp(NewCC, NewAnd, NewOr);
592 const APInt *ConstB, *ConstD;
602 APInt NewMask = *ConstB & *ConstD;
603 if (NewMask == *ConstB)
605 else if (NewMask == *ConstD)
614 APInt NewMask = *ConstB | *ConstD;
615 if (NewMask == *ConstB)
617 else if (NewMask == *ConstD)
644 const APInt *OldConstC, *OldConstE;
650 const APInt ConstC = PredL !=
CC ? *ConstB ^ *OldConstC : *OldConstC;
651 const APInt ConstE = PredR !=
CC ? *ConstD ^ *OldConstE : *OldConstE;
653 if (((*ConstB & *ConstD) & (ConstC ^ ConstE)).getBoolValue())
654 return IsNot ? nullptr : ConstantInt::get(
LHS->
getType(), !IsAnd);
656 if (IsNot && !ConstB->
isSubsetOf(*ConstD) && !ConstD->isSubsetOf(*ConstB))
661 BD = *ConstB & *ConstD;
662 CE = ConstC & ConstE;
664 BD = *ConstB | *ConstD;
665 CE = ConstC | ConstE;
668 Value *CEVal = ConstantInt::get(
A->getType(), CE);
673 return FoldBMixed(NewCC,
false);
675 return FoldBMixed(NewCC,
true);
725 default:
return nullptr;
749 if (
LHS->getPredicate() != Pred ||
RHS->getPredicate() != Pred)
780Value *InstCombinerImpl::foldAndOrOfICmpsOfAndWithPow2(
ICmpInst *LHS,
786 if (
LHS->getPredicate() != Pred ||
RHS->getPredicate() != Pred)
796 if (L1 ==
R2 || L2 ==
R2)
854 auto tryToMatchSignedTruncationCheck = [](
ICmpInst *ICmp,
Value *&
X,
855 APInt &SignBitMask) ->
bool {
856 const APInt *I01, *I1;
860 I1->ugt(*I01) && I01->
shl(1) == *I1))
872 if (tryToMatchSignedTruncationCheck(ICmp1, X1, HighestBit))
874 else if (tryToMatchSignedTruncationCheck(ICmp0, X1, HighestBit))
879 assert(HighestBit.
isPowerOf2() &&
"expected to be power of two (non-zero)");
883 APInt &UnsetBitsMask) ->
bool {
891 UnsetBitsMask = Res->Mask;
899 UnsetBitsMask = *Mask;
908 if (!tryToDecompose(OtherICmp, X0, UnsetBitsMask))
911 assert(!UnsetBitsMask.
isZero() &&
"empty mask makes no sense.");
926 APInt SignBitsMask = ~(HighestBit - 1U);
933 if (!UnsetBitsMask.
isSubsetOf(SignBitsMask)) {
934 APInt OtherHighestBit = (~UnsetBitsMask) + 1U;
942 return Builder.
CreateICmpULT(
X, ConstantInt::get(
X->getType(), HighestBit),
943 CxtI.
getName() +
".simplified");
960 auto *CtPop = cast<Instruction>(Cmp0->
getOperand(0));
963 CtPop->dropPoisonGeneratingAnnotations();
965 return Builder.
CreateICmpUGT(CtPop, ConstantInt::get(CtPop->getType(), 1));
969 CtPop->dropPoisonGeneratingAnnotations();
971 return Builder.
CreateICmpULT(CtPop, ConstantInt::get(CtPop->getType(), 2));
996 auto *CtPop = cast<Instruction>(Cmp1->
getOperand(0));
998 CtPop->dropPoisonGeneratingAnnotations();
1000 return Builder.
CreateICmpEQ(CtPop, ConstantInt::get(CtPop->getType(), 1));
1008 auto *CtPop = cast<Instruction>(Cmp1->
getOperand(0));
1010 CtPop->dropPoisonGeneratingAnnotations();
1012 return Builder.
CreateICmpNE(CtPop, ConstantInt::get(CtPop->getType(), 1));
1026 "Expected equality predicates for masked type of icmps.");
1046 const APInt *BCst, *DCst, *ECst;
1049 (isa<PoisonValue>(
B) ||
1054 if (
const auto *BVTy = dyn_cast<VectorType>(
B->getType())) {
1055 const auto *BFVTy = dyn_cast<FixedVectorType>(BVTy);
1056 const auto *BConst = dyn_cast<Constant>(
B);
1057 const auto *DConst = dyn_cast<Constant>(
D);
1058 const auto *EConst = dyn_cast<Constant>(E);
1060 if (!BFVTy || !BConst || !DConst || !EConst)
1063 for (
unsigned I = 0;
I != BFVTy->getNumElements(); ++
I) {
1064 const auto *BElt = BConst->getAggregateElement(
I);
1065 const auto *DElt = DConst->getAggregateElement(
I);
1066 const auto *EElt = EConst->getAggregateElement(
I);
1068 if (!BElt || !DElt || !EElt)
1070 if (!isReducible(BElt, DElt, EElt))
1075 if (!isReducible(
B,
D, E))
1093 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *E =
nullptr;
1099 std::optional<std::pair<unsigned, unsigned>> MaskPair =
1105 unsigned CmpMask0 = MaskPair->first;
1106 unsigned CmpMask1 = MaskPair->second;
1107 if ((CmpMask0 &
Mask_AllZeros) && (CmpMask1 == compareBMask)) {
1111 }
else if ((CmpMask0 == compareBMask) && (CmpMask1 &
Mask_AllZeros)) {
1122 ICmpInst *UnsignedICmp,
bool IsAnd,
1134 if (
match(UnsignedICmp,
1150 IsAnd && GetKnownNonZeroAndOther(
B,
A))
1153 !IsAnd && GetKnownNonZeroAndOther(
B,
A))
1170 return std::nullopt;
1172 unsigned NumOriginalBits =
X->getType()->getScalarSizeInBits();
1173 unsigned NumExtractedBits = V->getType()->getScalarSizeInBits();
1179 Shift->
ule(NumOriginalBits - NumExtractedBits))
1181 return {{
X, 0, NumExtractedBits}};
1189 Type *TruncTy = V->getType()->getWithNewBitWidth(
P.NumBits);
1190 if (TruncTy != V->getType())
1198Value *InstCombinerImpl::foldEqOfParts(
Value *Cmp0,
Value *Cmp1,
bool IsAnd) {
1203 auto GetMatchPart = [&](
Value *CmpV,
1204 unsigned OpNo) -> std::optional<IntPart> {
1213 return {{OpNo == 0 ?
X :
Y, 0, 1}};
1215 auto *
Cmp = dyn_cast<ICmpInst>(CmpV);
1217 return std::nullopt;
1219 if (Pred ==
Cmp->getPredicate())
1228 return std::nullopt;
1237 return std::nullopt;
1239 return std::nullopt;
1244 return {{
I->getOperand(OpNo),
From,
C->getBitWidth() -
From}};
1247 std::optional<IntPart> L0 = GetMatchPart(Cmp0, 0);
1248 std::optional<IntPart> R0 = GetMatchPart(Cmp0, 1);
1249 std::optional<IntPart> L1 = GetMatchPart(Cmp1, 0);
1250 std::optional<IntPart> R1 = GetMatchPart(Cmp1, 1);
1251 if (!L0 || !R0 || !L1 || !R1)
1256 if (L0->From != L1->From || R0->From != R1->From) {
1257 if (L0->From != R1->From || R0->From != L1->From)
1264 if (L0->StartBit + L0->NumBits != L1->StartBit ||
1265 R0->StartBit + R0->NumBits != R1->StartBit) {
1266 if (L1->StartBit + L1->NumBits != L0->StartBit ||
1267 R1->StartBit + R1->NumBits != R0->StartBit)
1274 IntPart L = {L0->From, L0->StartBit, L0->NumBits + L1->NumBits};
1275 IntPart R = {R0->From, R0->StartBit, R0->NumBits + R1->NumBits};
1285 bool IsAnd,
bool IsLogical,
1314 if (!SubstituteCmp) {
1324 return Builder.
CreateBinOp(IsAnd ? Instruction::And : Instruction::Or, Cmp0,
1332Value *InstCombinerImpl::foldAndOrOfICmpsUsingRanges(
ICmpInst *ICmp1,
1337 const APInt *C1, *C2;
1344 const APInt *Offset1 =
nullptr, *Offset2 =
nullptr;
1379 if (!LowerDiff.
isPowerOf2() || LowerDiff != UpperDiff ||
1392 CR->getEquivalentICmp(NewPred, NewC,
Offset);
1424 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1425 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1434 FMF &=
RHS->getFastMathFlags();
1441 bool IsAnd,
bool IsLogicalSelect) {
1442 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1443 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1446 if (LHS0 == RHS1 && RHS0 == LHS1) {
1466 if (LHS0 == RHS0 && LHS1 == RHS1) {
1469 unsigned NewPred = IsAnd ? FCmpCodeL & FCmpCodeR : FCmpCodeL | FCmpCodeR;
1475 FMF &=
RHS->getFastMathFlags();
1482 if (!IsLogicalSelect &&
1497 RHS->getFastMathFlags());
1517 auto [ClassValRHS, ClassMaskRHS] =
1520 auto [ClassValLHS, ClassMaskLHS] =
1522 if (ClassValLHS == ClassValRHS) {
1523 unsigned CombinedMask = IsAnd ? (ClassMaskLHS & ClassMaskRHS)
1524 : (ClassMaskLHS | ClassMaskRHS);
1526 Intrinsic::is_fpclass, {ClassValLHS->getType()},
1555 if (IsLessThanOrLessEqual(IsAnd ? PredR : PredL)) {
1559 if (IsLessThanOrLessEqual(IsAnd ? PredL : PredR)) {
1562 if (!IsLogicalSelect)
1563 NewFlag |=
RHS->getFastMathFlags();
1568 ConstantFP::get(LHS0->
getType(), *LHSC));
1579 auto *FCmp = dyn_cast<FCmpInst>(
Op);
1580 if (!FCmp || !FCmp->hasOneUse())
1583 std::tie(ClassVal, ClassMask) =
1584 fcmpToClassTest(FCmp->getPredicate(), *FCmp->getParent()->getParent(),
1585 FCmp->getOperand(0), FCmp->getOperand(1));
1586 return ClassVal !=
nullptr;
1597 Value *ClassVal0 =
nullptr;
1598 Value *ClassVal1 =
nullptr;
1615 ClassVal0 == ClassVal1) {
1616 unsigned NewClassMask;
1618 case Instruction::And:
1619 NewClassMask = ClassMask0 & ClassMask1;
1621 case Instruction::Or:
1622 NewClassMask = ClassMask0 | ClassMask1;
1624 case Instruction::Xor:
1625 NewClassMask = ClassMask0 ^ ClassMask1;
1632 auto *
II = cast<IntrinsicInst>(Op0);
1634 1, ConstantInt::get(
II->getArgOperand(1)->getType(), NewClassMask));
1639 auto *
II = cast<IntrinsicInst>(Op1);
1641 1, ConstantInt::get(
II->getArgOperand(1)->getType(), NewClassMask));
1661Instruction *InstCombinerImpl::canonicalizeConditionalNegationViaMathToSelect(
1663 assert(
I.getOpcode() == BinaryOperator::Xor &&
"Only for xor!");
1668 !
Cond->getType()->isIntOrIntVectorTy(1) ||
1682 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1683 "Expecting and/or op for fcmp transform");
1702 X->getType() !=
Y->getType())
1706 X->getType() !=
Y->getType())
1712 if (
auto *NewFCmpInst = dyn_cast<FCmpInst>(NewFCmp)) {
1714 NewFCmpInst->copyIRFlags(Op0);
1715 NewFCmpInst->andIRFlags(BO10);
1726 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1727 "Trying to match De Morgan's Laws with something other than and/or");
1731 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1733 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1759bool InstCombinerImpl::shouldOptimizeCast(
CastInst *CI) {
1768 if (
const auto *PrecedingCI = dyn_cast<CastInst>(CastSrc))
1769 if (isEliminableCastPair(PrecedingCI, CI))
1795 return new ZExtInst(NewOp, DestTy);
1803 return new SExtInst(NewOp, DestTy);
1812 auto LogicOpc =
I.getOpcode();
1813 assert(
I.isBitwiseLogicOp() &&
"Unexpected opcode for bitwise logic folding");
1815 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1821 auto FoldBitwiseICmpZeroWithICmp = [&](
Value *Op0,
1836 auto *ICmpR = cast<ZExtInst>(Op1)->getOperand(0);
1842 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op0, Op1))
1845 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op1, Op0))
1848 CastInst *Cast0 = dyn_cast<CastInst>(Op0);
1854 Type *DestTy =
I.getType();
1862 CastInst *Cast1 = dyn_cast<CastInst>(Op1);
1879 unsigned XNumBits =
X->getType()->getScalarSizeInBits();
1880 unsigned YNumBits =
Y->getType()->getScalarSizeInBits();
1881 if (XNumBits < YNumBits)
1899 shouldOptimizeCast(Cast0) && shouldOptimizeCast(Cast1)) {
1910 assert(
I.getOpcode() == Instruction::And);
1911 Value *Op0 =
I.getOperand(0);
1912 Value *Op1 =
I.getOperand(1);
1920 return BinaryOperator::CreateXor(
A,
B);
1936 assert(
I.getOpcode() == Instruction::Or);
1937 Value *Op0 =
I.getOperand(0);
1938 Value *Op1 =
I.getOperand(1);
1963 return BinaryOperator::CreateXor(
A,
B);
1983 Value *Op0 =
And.getOperand(0), *Op1 =
And.getOperand(1);
1997 if (!isa<VectorType>(Ty) && !shouldChangeType(Ty,
X->getType()))
2004 if (Opc == Instruction::LShr || Opc == Instruction::Shl)
2021 assert(Opcode == Instruction::And || Opcode == Instruction::Or);
2025 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
2027 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2034 const auto matchNotOrAnd =
2035 [Opcode, FlippedOpcode](
Value *
Op,
auto m_A,
auto m_B,
auto m_C,
2036 Value *&
X,
bool CountUses =
false) ->
bool {
2037 if (CountUses && !
Op->hasOneUse())
2044 return !CountUses ||
X->hasOneUse();
2060 return (Opcode == Instruction::Or)
2070 return (Opcode == Instruction::Or)
2093 if (Opcode == Instruction::Or && Op0->
hasOneUse() &&
2100 Value *
Or = cast<BinaryOperator>(
X)->getOperand(0);
2132 return (Opcode == Instruction::Or)
2134 : BinaryOperator::CreateOr(
Xor,
X);
2168 if (!isa<Constant>(
X) && !isa<Constant>(
Y) && !isa<Constant>(Z)) {
2170 if (!
X->hasOneUse()) {
2175 if (!
Y->hasOneUse()) {
2196 Type *Ty =
I.getType();
2198 Value *Op0 =
I.getOperand(0);
2199 Value *Op1 =
I.getOperand(1);
2211 case Instruction::And:
2212 if (
C->countl_one() < LastOneMath)
2215 case Instruction::Xor:
2216 case Instruction::Or:
2217 if (
C->countl_zero() < LastOneMath)
2226 ConstantInt::get(Ty, *C2), Op0);
2233 assert((
I.isBitwiseLogicOp() ||
I.getOpcode() == Instruction::Add) &&
2234 "Unexpected opcode");
2237 Constant *ShiftedC1, *ShiftedC2, *AddC;
2238 Type *Ty =
I.getType();
2252 auto *Op0Inst = dyn_cast<Instruction>(
I.getOperand(0));
2253 auto *Op1Inst = dyn_cast<Instruction>(
I.getOperand(1));
2254 if (!Op0Inst || !Op1Inst)
2260 if (ShiftOp != Op1Inst->getOpcode())
2264 if (
I.getOpcode() == Instruction::Add && ShiftOp != Instruction::Shl)
2284 assert(
I.isBitwiseLogicOp() &&
"Should and/or/xor");
2285 if (!
I.getOperand(0)->hasOneUse())
2292 if (
Y && (!
Y->hasOneUse() ||
X->getIntrinsicID() !=
Y->getIntrinsicID()))
2298 if (!
Y && (!(IID == Intrinsic::bswap || IID == Intrinsic::bitreverse) ||
2303 case Intrinsic::fshl:
2304 case Intrinsic::fshr: {
2305 if (
X->getOperand(2) !=
Y->getOperand(2))
2308 Builder.
CreateBinOp(
I.getOpcode(),
X->getOperand(0),
Y->getOperand(0));
2310 Builder.
CreateBinOp(
I.getOpcode(),
X->getOperand(1),
Y->getOperand(1));
2315 case Intrinsic::bswap:
2316 case Intrinsic::bitreverse: {
2318 I.getOpcode(),
X->getOperand(0),
2319 Y ?
Y->getOperand(0)
2320 : ConstantInt::get(
I.getType(), IID == Intrinsic::bswap
2340 unsigned Depth = 0) {
2347 auto *
I = dyn_cast<BinaryOperator>(V);
2348 if (!
I || !
I->isBitwiseLogicOp() ||
Depth >= 3)
2351 if (!
I->hasOneUse())
2352 SimplifyOnly =
true;
2355 SimplifyOnly, IC,
Depth + 1);
2357 SimplifyOnly, IC,
Depth + 1);
2358 if (!NewOp0 && !NewOp1)
2362 NewOp0 =
I->getOperand(0);
2364 NewOp1 =
I->getOperand(1);
2379 Type *Ty =
I.getType();
2413 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2448 Constant *NewC = ConstantInt::get(Ty, *
C & *XorC);
2451 return BinaryOperator::CreateXor(
And, NewC);
2462 APInt Together = *
C & *OrC;
2465 return BinaryOperator::CreateOr(
And, ConstantInt::get(Ty, Together));
2469 const APInt *ShiftC;
2471 ShiftC->
ult(Width)) {
2476 Constant *ShAmtC = ConstantInt::get(Ty, ShiftC->
zext(Width));
2477 return BinaryOperator::CreateLShr(Sext, ShAmtC);
2485 return BinaryOperator::CreateLShr(
X, ConstantInt::get(Ty, *ShiftC));
2493 if (Op0->
hasOneUse() &&
C->isPowerOf2() && (*AddC & (*
C - 1)) == 0) {
2494 assert((*
C & *AddC) != 0 &&
"Expected common bit");
2496 return BinaryOperator::CreateXor(NewAnd, Op1);
2503 switch (
B->getOpcode()) {
2504 case Instruction::Xor:
2505 case Instruction::Or:
2506 case Instruction::Mul:
2507 case Instruction::Add:
2508 case Instruction::Sub:
2524 C->isIntN(
X->getType()->getScalarSizeInBits())) {
2525 unsigned XWidth =
X->getType()->getScalarSizeInBits();
2526 Constant *TruncC1 = ConstantInt::get(
X->getType(), C1->
trunc(XWidth));
2530 Constant *TruncC = ConstantInt::get(
X->getType(),
C->trunc(XWidth));
2540 C->isMask(
X->getType()->getScalarSizeInBits())) {
2550 C->isMask(
X->getType()->getScalarSizeInBits())) {
2584 if (
C->isPowerOf2() &&
2587 int Log2C =
C->exactLogBase2();
2589 cast<BinaryOperator>(Op0)->getOpcode() == Instruction::Shl;
2590 int BitNum = IsShiftLeft ? Log2C - Log2ShiftC : Log2ShiftC - Log2C;
2591 assert(BitNum >= 0 &&
"Expected demanded bits to handle impossible mask");
2624 if (Cmp && Cmp->isZeroValue()) {
2649 Attribute::NoImplicitFloat)) {
2665 X->getType()->getScalarSizeInBits())))) {
2667 return BinaryOperator::CreateAnd(SExt, Op1);
2673 if (
I.getType()->isIntOrIntVectorTy(1)) {
2674 if (
auto *SI0 = dyn_cast<SelectInst>(Op0)) {
2676 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
true))
2679 if (
auto *SI1 = dyn_cast<SelectInst>(Op1)) {
2681 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
true))
2696 return BinaryOperator::CreateAnd(Op0,
B);
2699 return BinaryOperator::CreateAnd(Op1,
B);
2707 if (NotC !=
nullptr)
2708 return BinaryOperator::CreateAnd(Op0, NotC);
2717 if (NotC !=
nullptr)
2727 return BinaryOperator::CreateAnd(
A,
B);
2735 return BinaryOperator::CreateAnd(
A,
B);
2755 foldBooleanAndOr(Op0, Op1,
I,
true,
false))
2761 bool IsLogical = isa<SelectInst>(Op1);
2763 if (
Value *Res = foldBooleanAndOr(Op0,
X,
I,
true, IsLogical))
2767 if (
Value *Res = foldBooleanAndOr(Op0,
Y,
I,
true,
2773 bool IsLogical = isa<SelectInst>(Op0);
2775 if (
Value *Res = foldBooleanAndOr(
X, Op1,
I,
true, IsLogical))
2779 if (
Value *Res = foldBooleanAndOr(
Y, Op1,
I,
true,
2788 if (
Instruction *CastedAnd = foldCastedBitwiseLogic(
I))
2801 A->getType()->isIntOrIntVectorTy(1))
2807 A->getType()->isIntOrIntVectorTy(1))
2812 A->getType()->isIntOrIntVectorTy(1))
2819 if (
A->getType()->isIntOrIntVectorTy(1))
2832 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2841 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2852 Value *Start =
nullptr, *Step =
nullptr;
2860 return Canonicalized;
2862 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
2874 return BinaryOperator::CreateAnd(V, Op1);
2878 return BinaryOperator::CreateAnd(Op0, V);
2885 bool MatchBitReversals) {
2893 for (
auto *Inst : Insts) {
2894 Inst->setDebugLoc(
I.getDebugLoc());
2900std::optional<std::pair<Intrinsic::ID, SmallVector<Value *, 3>>>
2904 assert(
Or.getOpcode() == BinaryOperator::Or &&
"Expecting or instruction");
2906 unsigned Width =
Or.getType()->getScalarSizeInBits();
2911 return std::nullopt;
2918 if (isa<BinaryOperator>(Or0) && isa<BinaryOperator>(Or1)) {
2919 Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
2925 return std::nullopt;
2928 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2934 Or1->
getOpcode() == BinaryOperator::LShr &&
2935 "Illegal or(shift,shift) pair");
2939 auto matchShiftAmount = [&](
Value *L,
Value *R,
unsigned Width) ->
Value * {
2941 const APInt *LI, *RI;
2943 if (LI->
ult(Width) && RI->
ult(Width) && (*LI + *RI) == Width)
2944 return ConstantInt::get(L->getType(), *LI);
2968 if (ShVal0 != ShVal1)
2979 unsigned Mask = Width - 1;
3003 Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, Width);
3005 ShAmt = matchShiftAmount(ShAmt1, ShAmt0, Width);
3009 return std::nullopt;
3011 FShiftArgs = {ShVal0, ShVal1, ShAmt};
3012 }
else if (isa<ZExtInst>(Or0) || isa<ZExtInst>(Or1)) {
3024 if (!isa<ZExtInst>(Or1))
3028 const APInt *ZextHighShlAmt;
3031 return std::nullopt;
3035 return std::nullopt;
3037 unsigned HighSize =
High->getType()->getScalarSizeInBits();
3038 unsigned LowSize =
Low->getType()->getScalarSizeInBits();
3041 if (ZextHighShlAmt->
ult(LowSize) || ZextHighShlAmt->
ugt(Width - HighSize))
3042 return std::nullopt;
3049 if (!isa<ZExtInst>(
Y))
3052 const APInt *ZextLowShlAmt;
3059 if (*ZextLowShlAmt + *ZextHighShlAmt != Width)
3065 ZextLowShlAmt->
ule(Width - LowSize) &&
"Invalid concat");
3067 FShiftArgs = {U, U, ConstantInt::get(Or0->
getType(), *ZextHighShlAmt)};
3072 if (FShiftArgs.
empty())
3073 return std::nullopt;
3075 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
3076 return std::make_pair(IID, FShiftArgs);
3082 auto [IID, FShiftArgs] = *Opt;
3094 assert(
Or.getOpcode() == Instruction::Or &&
"bswap requires an 'or'");
3095 Value *Op0 =
Or.getOperand(0), *Op1 =
Or.getOperand(1);
3099 if ((Width & 1) != 0)
3101 unsigned HalfWidth = Width / 2;
3104 if (!isa<ZExtInst>(Op0))
3108 Value *LowerSrc, *ShlVal, *UpperSrc;
3121 NewUpper = Builder.
CreateShl(NewUpper, HalfWidth);
3128 Value *LowerBSwap, *UpperBSwap;
3131 return ConcatIntrinsicCalls(Intrinsic::bswap, UpperBSwap, LowerBSwap);
3135 Value *LowerBRev, *UpperBRev;
3138 return ConcatIntrinsicCalls(Intrinsic::bitreverse, UpperBRev, LowerBRev);
3145 unsigned NumElts = cast<FixedVectorType>(C1->
getType())->getNumElements();
3146 for (
unsigned i = 0; i != NumElts; ++i) {
3149 if (!EltC1 || !EltC2)
3168 Type *Ty =
A->getType();
3184 if (
A->getType()->isIntOrIntVectorTy()) {
3186 if (NumSignBits ==
A->getType()->getScalarSizeInBits() &&
3209 Cond->getType()->isIntOrIntVectorTy(1)) {
3235 Cond->getType()->isIntOrIntVectorTy(1) &&
3249 Value *
D,
bool InvertFalseVal) {
3252 Type *OrigType =
A->getType();
3255 if (
Value *
Cond = getSelectCondition(
A,
C, InvertFalseVal)) {
3260 Type *SelTy =
A->getType();
3261 if (
auto *VecTy = dyn_cast<VectorType>(
Cond->getType())) {
3263 unsigned Elts = VecTy->getElementCount().getKnownMinValue();
3284 bool IsAnd,
bool IsLogical,
3291 IsAnd ?
LHS->getInversePredicate() :
LHS->getPredicate();
3293 IsAnd ?
RHS->getInversePredicate() :
RHS->getPredicate();
3302 auto MatchRHSOp = [LHS0, CInt](
const Value *RHSOp) {
3305 (CInt->
isZero() && RHSOp == LHS0);
3336 if (
Value *V = foldAndOrOfICmpsOfAndWithPow2(LHS, RHS, &
I, IsAnd, IsLogical))
3340 Value *LHS0 =
LHS->getOperand(0), *RHS0 =
RHS->getOperand(0);
3341 Value *LHS1 =
LHS->getOperand(1), *RHS1 =
RHS->getOperand(1);
3343 const APInt *LHSC =
nullptr, *RHSC =
nullptr;
3350 if (LHS0 == RHS1 && LHS1 == RHS0) {
3354 if (LHS0 == RHS0 && LHS1 == RHS1) {
3357 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
3386 RHS->setSameSign(
false);
3412 if (IsAnd && !IsLogical)
3469 const APInt *AndC, *SmallC =
nullptr, *BigC =
nullptr;
3483 if (SmallC && BigC) {
3484 unsigned BigBitSize = BigC->getBitWidth();
3503 bool TrueIfSignedL, TrueIfSignedR;
3509 if ((TrueIfSignedL && !TrueIfSignedR &&
3512 (!TrueIfSignedL && TrueIfSignedR &&
3519 if ((TrueIfSignedL && !TrueIfSignedR &&
3522 (!TrueIfSignedL && TrueIfSignedR &&
3531 return foldAndOrOfICmpsUsingRanges(LHS, RHS, IsAnd);
3542 if (
auto *LHSCmp = dyn_cast<ICmpInst>(LHS))
3543 if (
auto *RHSCmp = dyn_cast<ICmpInst>(RHS))
3544 if (
Value *Res = foldAndOrOfICmps(LHSCmp, RHSCmp,
I, IsAnd, IsLogical))
3547 if (
auto *LHSCmp = dyn_cast<FCmpInst>(LHS))
3548 if (
auto *RHSCmp = dyn_cast<FCmpInst>(RHS))
3549 if (
Value *Res = foldLogicOfFCmps(LHSCmp, RHSCmp, IsAnd, IsLogical))
3552 if (
Value *Res = foldEqOfParts(LHS, RHS, IsAnd))
3560 assert(
I.getOpcode() == Instruction::Or &&
3561 "Simplification only supports or at the moment.");
3563 Value *Cmp1, *Cmp2, *Cmp3, *Cmp4;
3615 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
3616 Type *Ty =
I.getType();
3618 if (
auto *SI0 = dyn_cast<SelectInst>(Op0)) {
3620 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
false))
3623 if (
auto *SI1 = dyn_cast<SelectInst>(Op1)) {
3625 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
false))
3649 if (cast<PossiblyDisjointInst>(
I).isDisjoint()) {
3667 return BinaryOperator::CreateXor(
Or, ConstantInt::get(Ty, *CV));
3675 return BinaryOperator::CreateMul(
X, IncrementY);
3684 const APInt *C0, *C1;
3703 if ((*C0 & *C1).
isZero()) {
3708 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
3709 return BinaryOperator::CreateAnd(
A, C01);
3715 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
3716 return BinaryOperator::CreateAnd(
B, C01);
3720 const APInt *C2, *C3;
3725 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
3726 return BinaryOperator::CreateAnd(
Or, C01);
3736 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D))
3738 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B))
3740 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D))
3742 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B))
3744 if (
Value *V = matchSelectFromAndOr(
B,
D,
A,
C))
3746 if (
Value *V = matchSelectFromAndOr(
B,
D,
C,
A))
3748 if (
Value *V = matchSelectFromAndOr(
D,
B,
A,
C))
3750 if (
Value *V = matchSelectFromAndOr(
D,
B,
C,
A))
3759 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D,
true))
3761 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B,
true))
3763 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D,
true))
3765 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B,
true))
3774 return BinaryOperator::CreateOr(Op0,
C);
3781 return BinaryOperator::CreateOr(Op1,
C);
3787 bool SwappedForXor =
false;
3790 SwappedForXor =
true;
3797 return BinaryOperator::CreateOr(Op0,
B);
3799 return BinaryOperator::CreateOr(Op0,
A);
3804 return BinaryOperator::CreateOr(
A,
B);
3832 return BinaryOperator::CreateOr(Nand,
C);
3840 foldBooleanAndOr(Op0, Op1,
I,
false,
false))
3846 bool IsLogical = isa<SelectInst>(Op1);
3848 if (
Value *Res = foldBooleanAndOr(Op0,
X,
I,
false, IsLogical))
3852 if (
Value *Res = foldBooleanAndOr(Op0,
Y,
I,
false,
3858 bool IsLogical = isa<SelectInst>(Op0);
3860 if (
Value *Res = foldBooleanAndOr(
X, Op1,
I,
false, IsLogical))
3864 if (
Value *Res = foldBooleanAndOr(
Y, Op1,
I,
false,
3885 A->getType()->isIntOrIntVectorTy(1))
3898 return BinaryOperator::CreateOr(Inner, CI);
3905 Value *
X =
nullptr, *
Y =
nullptr;
3937 return BinaryOperator::CreateXor(
A,
B);
3953 Value *
Mul, *Ov, *MulIsNotZero, *UMulWithOv;
3970 if (
match(UMulWithOv, m_Intrinsic<Intrinsic::umul_with_overflow>(
3974 return BinaryOperator::CreateAnd(NotNullA, NotNullB);
3983 const APInt *C1, *C2;
3999 : C2->
uadd_ov(*C1, Overflow));
4003 return BinaryOperator::CreateOr(Ov, NewCmp);
4023 Value *Start =
nullptr, *Step =
nullptr;
4041 return BinaryOperator::CreateOr(
4053 return BinaryOperator::CreateOr(
4061 return Canonicalized;
4063 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
4084 Attribute::NoImplicitFloat)) {
4097 if ((KnownX.
One & *C2) == *C2)
4098 return BinaryOperator::CreateAnd(
X, ConstantInt::get(Ty, *C1 | *C2));
4107 return BinaryOperator::CreateOr(V, Op1);
4111 return BinaryOperator::CreateOr(Op0, V);
4113 if (cast<PossiblyDisjointInst>(
I).isDisjoint())
4124 assert(
I.getOpcode() == Instruction::Xor);
4125 Value *Op0 =
I.getOperand(0);
4126 Value *Op1 =
I.getOperand(1);
4137 return BinaryOperator::CreateXor(
A,
B);
4145 return BinaryOperator::CreateXor(
A,
B);
4153 return BinaryOperator::CreateXor(
A,
B);
4175 assert(
I.getOpcode() == Instruction::Xor &&
I.getOperand(0) == LHS &&
4176 I.getOperand(1) == RHS &&
"Should be 'xor' with these operands");
4179 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
4180 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
4183 if (LHS0 == RHS1 && LHS1 == RHS0) {
4187 if (LHS0 == RHS0 && LHS1 == RHS1) {
4190 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
4198 const APInt *LC, *RC;
4207 bool TrueIfSignedL, TrueIfSignedR;
4223 if (CRUnion && CRIntersect)
4224 if (
auto CR = CRUnion->exactIntersectWith(CRIntersect->inverse())) {
4225 if (CR->isFullSet())
4227 if (CR->isEmptySet())
4232 CR->getEquivalentICmp(NewPred, NewC,
Offset);
4241 ConstantInt::get(Ty, NewC));
4259 if (OrICmp == LHS && AndICmp == RHS) {
4264 if (OrICmp == RHS && AndICmp == LHS) {
4271 Y->setPredicate(
Y->getInversePredicate());
4273 if (!
Y->hasOneUse()) {
4284 Y->replaceUsesWithIf(NotY,
4285 [NotY](
Use &U) {
return U.getUser() != NotY; });
4325 return BinaryOperator::CreateXor(NewA,
X);
4331 Type *EltTy =
C->getType()->getScalarType();
4337 return BinaryOperator::CreateOr(
LHS,
RHS);
4352 return A ==
C ||
A ==
D ||
B ==
C ||
B ==
D;
4361 return BinaryOperator::CreateOr(
X, NotY);
4369 return BinaryOperator::CreateOr(
Y, NotX);
4379 assert(
Xor.getOpcode() == Instruction::Xor &&
"Expected an xor instruction.");
4385 Value *Op0 =
Xor.getOperand(0), *Op1 =
Xor.getOperand(1);
4400 auto *
Add = cast<BinaryOperator>(Op0);
4401 Value *NegA =
Add->hasNoUnsignedWrap()
4411 auto *
I = dyn_cast<Instruction>(
Op);
4418 auto *
I = cast<Instruction>(
Op);
4421 Op->replaceUsesWithIf(NotOp,
4422 [NotOp](
Use &U) {
return U.getUser() != NotOp; });
4444 bool IsBinaryOp = isa<BinaryOperator>(
I);
4484 bool IsBinaryOp = isa<BinaryOperator>(
I);
4486 Value *NotOp0 =
nullptr;
4487 Value *NotOp1 =
nullptr;
4488 Value **OpToInvert =
nullptr;
4533 Type *Ty =
I.getType();
4537 return BinaryOperator::CreateOr(
X, NotY);
4548 return BinaryOperator::CreateAnd(
X, NotY);
4563 return BinaryOperator::CreateAnd(DecX, NotY);
4568 return BinaryOperator::CreateAShr(
X,
Y);
4574 return BinaryOperator::CreateAShr(
X,
Y);
4630 Type *SextTy = cast<BitCastOperator>(NotOp)->getSrcTy();
4636 if (
auto *NotOpI = dyn_cast<Instruction>(NotOp))
4643 auto *
II = dyn_cast<IntrinsicInst>(NotOp);
4644 if (
II &&
II->hasOneUse()) {
4652 if (
II->getIntrinsicID() == Intrinsic::is_fpclass) {
4653 ConstantInt *ClassMask = cast<ConstantInt>(
II->getArgOperand(1));
4655 1, ConstantInt::get(ClassMask->
getType(),
4670 if (
auto *Sel = dyn_cast<SelectInst>(NotOp)) {
4671 Value *TV = Sel->getTrueValue();
4672 Value *FV = Sel->getFalseValue();
4673 auto *CmpT = dyn_cast<CmpInst>(TV);
4674 auto *CmpF = dyn_cast<CmpInst>(FV);
4675 bool InvertibleT = (CmpT && CmpT->hasOneUse()) || isa<Constant>(TV);
4676 bool InvertibleF = (CmpF && CmpF->hasOneUse()) || isa<Constant>(FV);
4677 if (InvertibleT && InvertibleF) {
4679 CmpT->setPredicate(CmpT->getInversePredicate());
4683 CmpF->setPredicate(CmpF->getInversePredicate());
4737 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
4745 return BinaryOperator::CreateXor(XorAC,
Y);
4748 return BinaryOperator::CreateXor(XorBC,
X);
4758 return BinaryOperator::CreateDisjointOr(Op0, Op1);
4760 return BinaryOperator::CreateOr(Op0, Op1);
4777 return BinaryOperator::CreateXor(
4800 *CA ==
X->getType()->getScalarSizeInBits() - 1 &&
4808 Type *Ty =
I.getType();
4816 return BinaryOperator::CreateSub(ConstantInt::get(Ty, *
C + *RHSC),
X);
4820 return BinaryOperator::CreateAdd(
X, ConstantInt::get(Ty, *
C + *RHSC));
4825 return BinaryOperator::CreateXor(
X, ConstantInt::get(Ty, *
C ^ *RHSC));
4830 auto *
II = dyn_cast<IntrinsicInst>(Op0);
4833 if ((IID == Intrinsic::ctlz || IID == Intrinsic::cttz) &&
4836 IID = (IID == Intrinsic::ctlz) ? Intrinsic::cttz : Intrinsic::ctlz;
4849 return BinaryOperator::CreateShl(NotX, ConstantInt::get(Ty, *
C));
4855 return BinaryOperator::CreateLShr(NotX, ConstantInt::get(Ty, *
C));
4874 Attribute::NoImplicitFloat)) {
4898 return BinaryOperator::CreateXor(Opnd0, ConstantInt::get(Ty, FoldConst));
4931 return BinaryOperator::CreateXor(
4937 return BinaryOperator::CreateXor(
4943 return BinaryOperator::CreateOr(
A,
B);
4947 return BinaryOperator::CreateOr(
A,
B);
4957 return BinaryOperator::CreateOr(
A,
B);
4972 if (
B ==
C ||
B ==
D)
4983 if (
I.getType()->isIntOrIntVectorTy(1) &&
4986 bool NeedFreeze = isa<SelectInst>(Op0) && isa<SelectInst>(Op1) &&
B ==
D;
4987 if (
B ==
C ||
B ==
D)
4999 if (
auto *
LHS = dyn_cast<ICmpInst>(
I.getOperand(0)))
5000 if (
auto *
RHS = dyn_cast<ICmpInst>(
I.getOperand(1)))
5004 if (
Instruction *CastedXor = foldCastedBitwiseLogic(
I))
5024 return Canonicalized;
5026 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
5029 if (
Instruction *Folded = canonicalizeConditionalNegationViaMathToSelect(
I))
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 Value * foldIsPowerOf2OrZero(ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd, InstCombiner::BuilderTy &Builder, InstCombinerImpl &IC)
Fold (icmp eq ctpop(X) 1) | (icmp eq X 0) into (icmp ult ctpop(X) 2) and fold (icmp ne ctpop(X) 1) & ...
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 * foldIsPowerOf2(ICmpInst *Cmp0, ICmpInst *Cmp1, bool JoinedByAnd, InstCombiner::BuilderTy &Builder, InstCombinerImpl &IC)
Reduce a pair of compares that check if a value has exactly 1 bit set.
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 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 * 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 * foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, Value *A, Value *B, 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 * 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 Value * foldOrOfInversions(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
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 Value * foldAndOrOfICmpsWithPow2AndWithZero(InstCombiner::BuilderTy &Builder, ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, const SimplifyQuery &Q)
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)
uint64_t IntrinsicInst * II
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
APInt bitcastToAPInt() const
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
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.
void clearSignBit()
Set the sign bit to 0.
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.
BinaryOps getOpcode() const
static BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
static 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.
static BinaryOperator * CreateWithCopiedFlags(BinaryOps Opc, Value *V1, Value *V2, Value *CopyO, const Twine &Name="", InsertPosition InsertBefore=nullptr)
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="", InsertPosition InsertBefore=nullptr)
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="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
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.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
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 * getZero(Type *Ty, bool Negative=false)
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.
CmpPredicate getInverseCmpPredicate() const
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 * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="", MDNode *FPMathTag=nullptr)
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 * 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.
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.
Instruction * foldAddLikeCommutative(Value *LHS, Value *RHS, bool NSW, bool NUW)
Common transforms for add / disjoint or.
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)
Value * SimplifyAddWithRemainder(BinaryOperator &I)
Tries to simplify add operations using the definition of remainder.
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 addToWorklist(Instruction *I)
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="", InsertPosition InsertBefore=nullptr, 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.
const fltSemantics & getFltSemantics() const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
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.
bool isIEEELikeFPTy() const
Return true if this is a well-behaved IEEE-like type, which has a IEEE compatible layout as defined b...
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
A Use represents the edge between a Value definition and its users.
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.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
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.
CmpClass_match< LHS, RHS, FCmpInst > m_FCmp(CmpPredicate &Pred, 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.
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.
match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)
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.
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)
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.
DisjointOr_match< LHS, RHS > m_DisjointOr(const LHS &L, const RHS &R)
constantexpr_match m_ConstantExpr()
Match a constant expression or a constant that contains a constant expression.
specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)
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.
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.
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.
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.
SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
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.
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.
SpecificCmpClass_match< LHS, RHS, FCmpInst > m_SpecificFCmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
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< 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)
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'.
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...
Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Instruction *I=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return true if the given value is known to have exactly one bit set when defined.
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 isGuaranteedNotToBeUndef(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be undef, but may be poison.
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 isKnownNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the given value is known be negative (i.e.
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 * simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an ICmpInst, fold the result or return null.
Value * simplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an And, fold the result or return null.
bool isKnownInversion(const Value *X, const Value *Y)
Return true iff:
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.
@ 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.
std::optional< DecomposedBitTest > decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate Pred, bool LookThroughTrunc=true, bool AllowNonZeroC=false)
Decompose an icmp into the form ((X & Mask) pred C) if possible.
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.
unsigned getICmpCode(CmpInst::Predicate Pred)
Encode a icmp predicate into a three bit mask.
bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
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