27using namespace PatternMatch;
29#define DEBUG_TYPE "instcombine"
60 "Lo is not < Hi in range emission code!");
62 Type *Ty = V->getType();
67 if (
isSigned ?
Lo.isMinSignedValue() :
Lo.isMinValue()) {
124 const APInt *ConstA =
nullptr, *ConstB =
nullptr, *ConstC =
nullptr;
129 bool IsAPow2 = ConstA && ConstA->
isPowerOf2();
130 bool IsBPow2 = ConstB && ConstB->isPowerOf2();
131 unsigned MaskVal = 0;
132 if (ConstC && ConstC->isZero()) {
151 }
else if (ConstA && ConstC && ConstC->
isSubsetOf(*ConstA)) {
161 }
else if (ConstB && ConstC && ConstC->isSubsetOf(*ConstB)) {
195 Y = ConstantInt::get(
X->getType(), Res->Mask);
196 Z = ConstantInt::get(
X->getType(), Res->C);
205static std::optional<std::pair<unsigned, unsigned>>
218 Value *L1, *L11, *L12, *L2, *L21, *L22;
220 L21 = L22 = L1 =
nullptr;
222 auto *LHSCMP = dyn_cast<ICmpInst>(
LHS);
227 if (!LHSCMP->getOperand(0)->getType()->isIntOrIntVectorTy())
230 PredL = LHSCMP->getPredicate();
231 L1 = LHSCMP->getOperand(0);
232 L2 = LHSCMP->getOperand(1);
253 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
256 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
264 auto *RHSCMP = dyn_cast<ICmpInst>(
RHS);
268 if (!RHSCMP->getOperand(0)->getType()->isIntOrIntVectorTy())
271 PredR = RHSCMP->getPredicate();
273 Value *R1 = RHSCMP->getOperand(0);
274 R2 = RHSCMP->getOperand(1);
283 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
288 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
306 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
310 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
327 }
else if (L12 ==
A) {
330 }
else if (L21 ==
A) {
333 }
else if (L22 ==
A) {
340 return std::optional<std::pair<unsigned, unsigned>>(
341 std::make_pair(LeftType, RightType));
363 const APInt *BCst, *DCst, *OrigECst;
374 APInt ECst = *OrigECst;
380 if (*BCst == 0 || *DCst == 0)
391 Attribute::StrictFP)) {
392 Type *Ty = Src->getType()->getScalarType();
399 APInt FractionBits = ~ExpBits;
401 if (*BCst != FractionBits)
426 if ((((*BCst & *DCst) & ECst) == 0) &&
427 (*BCst & (*BCst ^ *DCst)).isPowerOf2()) {
428 APInt BorD = *BCst | *DCst;
429 APInt BandBxorDorE = (*BCst & (*BCst ^ *DCst)) | ECst;
430 Value *NewMask = ConstantInt::get(
A->getType(), BorD);
431 Value *NewMaskedValue = ConstantInt::get(
A->getType(), BandBxorDorE);
433 return Builder.
CreateICmp(NewCC, NewAnd, NewMaskedValue);
436 auto IsSubSetOrEqual = [](
const APInt *C1,
const APInt *C2) {
437 return (*C1 & *C2) == *C1;
439 auto IsSuperSetOrEqual = [](
const APInt *C1,
const APInt *C2) {
440 return (*C1 & *C2) == *C2;
449 if (!IsSubSetOrEqual(BCst, DCst) && !IsSuperSetOrEqual(BCst, DCst))
461 if (IsSubSetOrEqual(BCst, DCst))
462 return ConstantInt::get(
LHS->
getType(), !IsAnd);
472 if (IsSuperSetOrEqual(BCst, DCst)) {
474 if (
auto *ICmp = dyn_cast<ICmpInst>(
RHS))
475 ICmp->setSameSign(
false);
481 assert(IsSubSetOrEqual(BCst, DCst) &&
"Precondition due to above code");
482 if ((*BCst & ECst) != 0) {
484 if (
auto *ICmp = dyn_cast<ICmpInst>(
RHS))
485 ICmp->setSameSign(
false);
492 return ConstantInt::get(
LHS->
getType(), !IsAnd);
504 "Expected equality predicates for masked type of icmps.");
516 LHS,
RHS, IsAnd,
A,
B,
D, E, PredL, PredR, Builder)) {
521 RHS,
LHS, IsAnd,
A,
D,
B,
C, PredR, PredL, Builder)) {
534 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *E =
nullptr;
536 std::optional<std::pair<unsigned, unsigned>> MaskPair =
541 "Expected equality predicates for masked type of icmps.");
542 unsigned LHSMask = MaskPair->first;
543 unsigned RHSMask = MaskPair->second;
544 unsigned Mask = LHSMask & RHSMask;
549 LHS,
RHS, IsAnd,
A,
B,
C,
D, E, PredL, PredR, LHSMask, RHSMask,
585 return Builder.
CreateICmp(NewCC, NewAnd, Zero);
594 return Builder.
CreateICmp(NewCC, NewAnd, NewOr);
606 const APInt *ConstB, *ConstD;
614 APInt NewMask = *ConstB & *ConstD;
615 if (NewMask == *ConstB)
617 if (NewMask == *ConstD) {
619 if (
auto *RHSI = dyn_cast<Instruction>(
RHS))
620 RHSI->dropPoisonGeneratingFlags();
631 APInt NewMask = *ConstB | *ConstD;
632 if (NewMask == *ConstB)
634 if (NewMask == *ConstD)
661 const APInt *OldConstC, *OldConstE;
667 const APInt ConstC = PredL != CC ? *ConstB ^ *OldConstC : *OldConstC;
668 const APInt ConstE = PredR != CC ? *ConstD ^ *OldConstE : *OldConstE;
670 if (((*ConstB & *ConstD) & (ConstC ^ ConstE)).getBoolValue())
671 return IsNot ? nullptr : ConstantInt::get(
LHS->
getType(), !IsAnd);
674 !ConstD->isSubsetOf(*ConstB))
679 BD = *ConstB & *ConstD;
680 CE = ConstC & ConstE;
682 BD = *ConstB | *ConstD;
683 CE = ConstC | ConstE;
686 Value *CEVal = ConstantInt::get(
A->getType(), CE);
691 return FoldBMixed(NewCC,
false);
693 return FoldBMixed(NewCC,
true);
761 default:
return nullptr;
785 if (
LHS->getPredicate() != Pred ||
RHS->getPredicate() != Pred)
849 auto tryToMatchSignedTruncationCheck = [](
ICmpInst *ICmp,
Value *&
X,
850 APInt &SignBitMask) ->
bool {
851 const APInt *I01, *I1;
855 I1->ugt(*I01) && I01->
shl(1) == *I1))
867 if (tryToMatchSignedTruncationCheck(ICmp1, X1, HighestBit))
869 else if (tryToMatchSignedTruncationCheck(ICmp0, X1, HighestBit))
874 assert(HighestBit.
isPowerOf2() &&
"expected to be power of two (non-zero)");
878 APInt &UnsetBitsMask) ->
bool {
887 UnsetBitsMask = Res->Mask;
897 if (!tryToDecompose(OtherICmp, X0, UnsetBitsMask))
900 assert(!UnsetBitsMask.
isZero() &&
"empty mask makes no sense.");
915 APInt SignBitsMask = ~(HighestBit - 1U);
922 if (!UnsetBitsMask.
isSubsetOf(SignBitsMask)) {
923 APInt OtherHighestBit = (~UnsetBitsMask) + 1U;
931 return Builder.
CreateICmpULT(
X, ConstantInt::get(
X->getType(), HighestBit),
932 CxtI.
getName() +
".simplified");
949 auto *CtPop = cast<Instruction>(Cmp0->
getOperand(0));
952 CtPop->dropPoisonGeneratingAnnotations();
954 return Builder.
CreateICmpUGT(CtPop, ConstantInt::get(CtPop->getType(), 1));
958 CtPop->dropPoisonGeneratingAnnotations();
960 return Builder.
CreateICmpULT(CtPop, ConstantInt::get(CtPop->getType(), 2));
985 auto *CtPop = cast<Instruction>(Cmp1->
getOperand(0));
987 CtPop->dropPoisonGeneratingAnnotations();
989 return Builder.
CreateICmpEQ(CtPop, ConstantInt::get(CtPop->getType(), 1));
997 auto *CtPop = cast<Instruction>(Cmp1->
getOperand(0));
999 CtPop->dropPoisonGeneratingAnnotations();
1001 return Builder.
CreateICmpNE(CtPop, ConstantInt::get(CtPop->getType(), 1));
1015 "Expected equality predicates for masked type of icmps.");
1035 const APInt *BCst, *DCst, *ECst;
1038 (isa<PoisonValue>(
B) ||
1043 if (
const auto *BVTy = dyn_cast<VectorType>(
B->getType())) {
1044 const auto *BFVTy = dyn_cast<FixedVectorType>(BVTy);
1045 const auto *BConst = dyn_cast<Constant>(
B);
1046 const auto *DConst = dyn_cast<Constant>(
D);
1047 const auto *EConst = dyn_cast<Constant>(E);
1049 if (!BFVTy || !BConst || !DConst || !EConst)
1052 for (
unsigned I = 0;
I != BFVTy->getNumElements(); ++
I) {
1053 const auto *BElt = BConst->getAggregateElement(
I);
1054 const auto *DElt = DConst->getAggregateElement(
I);
1055 const auto *EElt = EConst->getAggregateElement(
I);
1057 if (!BElt || !DElt || !EElt)
1059 if (!isReducible(BElt, DElt, EElt))
1064 if (!isReducible(
B,
D, E))
1082 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *E =
nullptr;
1087 std::optional<std::pair<unsigned, unsigned>> MaskPair =
1093 unsigned CmpMask0 = MaskPair->first;
1094 unsigned CmpMask1 = MaskPair->second;
1095 if ((CmpMask0 &
Mask_AllZeros) && (CmpMask1 == compareBMask)) {
1099 }
else if ((CmpMask0 == compareBMask) && (CmpMask1 &
Mask_AllZeros)) {
1110 ICmpInst *UnsignedICmp,
bool IsAnd,
1122 if (
match(UnsignedICmp,
1138 IsAnd && GetKnownNonZeroAndOther(
B,
A))
1141 !IsAnd && GetKnownNonZeroAndOther(
B,
A))
1158 return std::nullopt;
1160 unsigned NumOriginalBits =
X->getType()->getScalarSizeInBits();
1161 unsigned NumExtractedBits = V->getType()->getScalarSizeInBits();
1167 Shift->
ule(NumOriginalBits - NumExtractedBits))
1169 return {{
X, 0, NumExtractedBits}};
1177 Type *TruncTy = V->getType()->getWithNewBitWidth(
P.NumBits);
1178 if (TruncTy != V->getType())
1186Value *InstCombinerImpl::foldEqOfParts(
Value *Cmp0,
Value *Cmp1,
bool IsAnd) {
1191 auto GetMatchPart = [&](
Value *CmpV,
1192 unsigned OpNo) -> std::optional<IntPart> {
1201 return {{OpNo == 0 ?
X :
Y, 0, 1}};
1203 auto *
Cmp = dyn_cast<ICmpInst>(CmpV);
1205 return std::nullopt;
1207 if (Pred ==
Cmp->getPredicate())
1216 return std::nullopt;
1225 return std::nullopt;
1227 return std::nullopt;
1232 return {{
I->getOperand(OpNo),
From,
C->getBitWidth() -
From}};
1235 std::optional<IntPart> L0 = GetMatchPart(Cmp0, 0);
1236 std::optional<IntPart> R0 = GetMatchPart(Cmp0, 1);
1237 std::optional<IntPart> L1 = GetMatchPart(Cmp1, 0);
1238 std::optional<IntPart> R1 = GetMatchPart(Cmp1, 1);
1239 if (!L0 || !R0 || !L1 || !R1)
1244 if (L0->From != L1->From || R0->From != R1->From) {
1245 if (L0->From != R1->From || R0->From != L1->From)
1252 if (L0->StartBit + L0->NumBits != L1->StartBit ||
1253 R0->StartBit + R0->NumBits != R1->StartBit) {
1254 if (L1->StartBit + L1->NumBits != L0->StartBit ||
1255 R1->StartBit + R1->NumBits != R0->StartBit)
1262 IntPart L = {L0->From, L0->StartBit, L0->NumBits + L1->NumBits};
1263 IntPart R = {R0->From, R0->StartBit, R0->NumBits + R1->NumBits};
1273 bool IsAnd,
bool IsLogical,
1302 if (!SubstituteCmp) {
1312 return Builder.
CreateBinOp(IsAnd ? Instruction::And : Instruction::Or, Cmp0,
1320Value *InstCombinerImpl::foldAndOrOfICmpsUsingRanges(
ICmpInst *ICmp1,
1325 const APInt *C1, *C2;
1332 const APInt *Offset1 =
nullptr, *Offset2 =
nullptr;
1352 const APInt *Mask1 =
nullptr, *Mask2 =
nullptr;
1353 bool MatchedAnd1 =
false, MatchedAnd2 =
false;
1354 if (V1 != V2 && AreContiguousRangePredicates(Pred1, Pred2, IsAnd)) {
1377 IsAnd ?
ICmpInst::getInverseCmpPredicate(Pred1) : Pred1, *C1);
1385 IsAnd ?
ICmpInst::getInverseCmpPredicate(Pred2) : Pred2, *C2);
1402 if (!LowerDiff.
isPowerOf2() || LowerDiff != UpperDiff ||
1415 CR->getEquivalentICmp(NewPred, NewC,
Offset);
1447 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1448 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1460 bool IsAnd,
bool IsLogicalSelect) {
1461 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1462 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1465 if (LHS0 == RHS1 && RHS0 == LHS1) {
1485 if (LHS0 == RHS0 && LHS1 == RHS1) {
1488 unsigned NewPred = IsAnd ? FCmpCodeL & FCmpCodeR : FCmpCodeL | FCmpCodeR;
1497 if (!IsLogicalSelect &&
1516 if (!IsLogicalSelect && IsAnd &&
1532 auto [ClassValRHS, ClassMaskRHS] =
1535 auto [ClassValLHS, ClassMaskLHS] =
1537 if (ClassValLHS == ClassValRHS) {
1538 unsigned CombinedMask = IsAnd ? (ClassMaskLHS & ClassMaskRHS)
1539 : (ClassMaskLHS | ClassMaskRHS);
1541 Intrinsic::is_fpclass, {ClassValLHS->getType()},
1570 if (IsLessThanOrLessEqual(IsAnd ? PredR : PredL)) {
1574 if (IsLessThanOrLessEqual(IsAnd ? PredL : PredR)) {
1576 if (!IsLogicalSelect)
1577 NewFlag |=
RHS->getFastMathFlags();
1582 PredL, FAbs, ConstantFP::get(LHS0->
getType(), *LHSC), NewFlag);
1593 auto *FCmp = dyn_cast<FCmpInst>(
Op);
1594 if (!FCmp || !FCmp->hasOneUse())
1597 std::tie(ClassVal, ClassMask) =
1598 fcmpToClassTest(FCmp->getPredicate(), *FCmp->getParent()->getParent(),
1599 FCmp->getOperand(0), FCmp->getOperand(1));
1600 return ClassVal !=
nullptr;
1611 Value *ClassVal0 =
nullptr;
1612 Value *ClassVal1 =
nullptr;
1629 ClassVal0 == ClassVal1) {
1630 unsigned NewClassMask;
1632 case Instruction::And:
1633 NewClassMask = ClassMask0 & ClassMask1;
1635 case Instruction::Or:
1636 NewClassMask = ClassMask0 | ClassMask1;
1638 case Instruction::Xor:
1639 NewClassMask = ClassMask0 ^ ClassMask1;
1646 auto *
II = cast<IntrinsicInst>(Op0);
1648 1, ConstantInt::get(
II->getArgOperand(1)->getType(), NewClassMask));
1653 auto *
II = cast<IntrinsicInst>(Op1);
1655 1, ConstantInt::get(
II->getArgOperand(1)->getType(), NewClassMask));
1675Instruction *InstCombinerImpl::canonicalizeConditionalNegationViaMathToSelect(
1677 assert(
I.getOpcode() == BinaryOperator::Xor &&
"Only for xor!");
1682 !
Cond->getType()->isIntOrIntVectorTy(1) ||
1696 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1697 "Expecting and/or op for fcmp transform");
1716 X->getType() !=
Y->getType())
1720 X->getType() !=
Y->getType())
1737 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1738 "Trying to match De Morgan's Laws with something other than and/or");
1742 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1744 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1770bool InstCombinerImpl::shouldOptimizeCast(
CastInst *CI) {
1779 if (
const auto *PrecedingCI = dyn_cast<CastInst>(CastSrc))
1780 if (isEliminableCastPair(PrecedingCI, CI))
1806 return new ZExtInst(NewOp, DestTy);
1814 return new SExtInst(NewOp, DestTy);
1823 auto LogicOpc =
I.getOpcode();
1824 assert(
I.isBitwiseLogicOp() &&
"Unexpected opcode for bitwise logic folding");
1826 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1832 auto FoldBitwiseICmpZeroWithICmp = [&](
Value *Op0,
1847 auto *ICmpR = cast<ZExtInst>(Op1)->getOperand(0);
1853 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op0, Op1))
1856 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op1, Op0))
1859 CastInst *Cast0 = dyn_cast<CastInst>(Op0);
1865 Type *DestTy =
I.getType();
1873 CastInst *Cast1 = dyn_cast<CastInst>(Op1);
1891 unsigned XNumBits =
X->getType()->getScalarSizeInBits();
1892 unsigned YNumBits =
Y->getType()->getScalarSizeInBits();
1893 if (XNumBits != YNumBits) {
1901 if (XNumBits < YNumBits) {
1903 }
else if (YNumBits < XNumBits) {
1910 auto *Disjoint = dyn_cast<PossiblyDisjointInst>(&
I);
1911 auto *NewDisjoint = dyn_cast<PossiblyDisjointInst>(NarrowLogic);
1912 if (Disjoint && NewDisjoint)
1913 NewDisjoint->setIsDisjoint(Disjoint->isDisjoint());
1925 if (shouldOptimizeCast(Cast0) && shouldOptimizeCast(Cast1)) {
1936 assert(
I.getOpcode() == Instruction::And);
1937 Value *Op0 =
I.getOperand(0);
1938 Value *Op1 =
I.getOperand(1);
1946 return BinaryOperator::CreateXor(
A,
B);
1962 assert(
I.getOpcode() == Instruction::Or);
1963 Value *Op0 =
I.getOperand(0);
1964 Value *Op1 =
I.getOperand(1);
1989 return BinaryOperator::CreateXor(
A,
B);
2009 Value *Op0 =
And.getOperand(0), *Op1 =
And.getOperand(1);
2023 if (!isa<VectorType>(Ty) && !shouldChangeType(Ty,
X->getType()))
2030 if (
Opc == Instruction::LShr ||
Opc == Instruction::Shl)
2047 assert(Opcode == Instruction::And || Opcode == Instruction::Or);
2051 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
2053 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2060 const auto matchNotOrAnd =
2061 [Opcode, FlippedOpcode](
Value *
Op,
auto m_A,
auto m_B,
auto m_C,
2062 Value *&
X,
bool CountUses =
false) ->
bool {
2063 if (CountUses && !
Op->hasOneUse())
2069 return !CountUses ||
X->hasOneUse();
2085 return (Opcode == Instruction::Or)
2095 return (Opcode == Instruction::Or)
2118 if (Opcode == Instruction::Or && Op0->
hasOneUse() &&
2125 Value *
Or = cast<BinaryOperator>(
X)->getOperand(0);
2156 return (Opcode == Instruction::Or)
2158 : BinaryOperator::CreateOr(
Xor,
X);
2192 if (!isa<Constant>(
X) && !isa<Constant>(
Y) && !isa<Constant>(Z)) {
2194 if (!
X->hasOneUse()) {
2199 if (!
Y->hasOneUse()) {
2220 Type *Ty =
I.getType();
2222 Value *Op0 =
I.getOperand(0);
2223 Value *Op1 =
I.getOperand(1);
2235 case Instruction::And:
2236 if (
C->countl_one() < LastOneMath)
2239 case Instruction::Xor:
2240 case Instruction::Or:
2241 if (
C->countl_zero() < LastOneMath)
2250 ConstantInt::get(Ty, *C2), Op0);
2257 assert((
I.isBitwiseLogicOp() ||
I.getOpcode() == Instruction::Add) &&
2258 "Unexpected opcode");
2261 Constant *ShiftedC1, *ShiftedC2, *AddC;
2262 Type *Ty =
I.getType();
2276 auto *Op0Inst = dyn_cast<Instruction>(
I.getOperand(0));
2277 auto *Op1Inst = dyn_cast<Instruction>(
I.getOperand(1));
2278 if (!Op0Inst || !Op1Inst)
2284 if (ShiftOp != Op1Inst->getOpcode())
2288 if (
I.getOpcode() == Instruction::Add && ShiftOp != Instruction::Shl)
2308 assert(
I.isBitwiseLogicOp() &&
"Should and/or/xor");
2309 if (!
I.getOperand(0)->hasOneUse())
2316 if (
Y && (!
Y->hasOneUse() ||
X->getIntrinsicID() !=
Y->getIntrinsicID()))
2322 if (!
Y && (!(IID == Intrinsic::bswap || IID == Intrinsic::bitreverse) ||
2327 case Intrinsic::fshl:
2328 case Intrinsic::fshr: {
2329 if (
X->getOperand(2) !=
Y->getOperand(2))
2332 Builder.
CreateBinOp(
I.getOpcode(),
X->getOperand(0),
Y->getOperand(0));
2334 Builder.
CreateBinOp(
I.getOpcode(),
X->getOperand(1),
Y->getOperand(1));
2339 case Intrinsic::bswap:
2340 case Intrinsic::bitreverse: {
2342 I.getOpcode(),
X->getOperand(0),
2343 Y ?
Y->getOperand(0)
2344 : ConstantInt::get(
I.getType(), IID == Intrinsic::bswap
2364 unsigned Depth = 0) {
2371 auto *
I = dyn_cast<BinaryOperator>(V);
2372 if (!
I || !
I->isBitwiseLogicOp() ||
Depth >= 3)
2375 if (!
I->hasOneUse())
2376 SimplifyOnly =
true;
2379 SimplifyOnly, IC,
Depth + 1);
2381 SimplifyOnly, IC,
Depth + 1);
2382 if (!NewOp0 && !NewOp1)
2386 NewOp0 =
I->getOperand(0);
2388 NewOp1 =
I->getOperand(1);
2404 bool RHSIsLogical) {
2408 if (
Value *Res = foldBooleanAndOr(LHS,
X,
I, IsAnd,
false))
2413 if (
Value *Res = foldBooleanAndOr(LHS,
Y,
I, IsAnd,
false))
2423 Type *Ty =
I.getType();
2457 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2491 Constant *NewC = ConstantInt::get(Ty, *
C & *XorC);
2494 return BinaryOperator::CreateXor(
And, NewC);
2505 APInt Together = *
C & *OrC;
2508 return BinaryOperator::CreateOr(
And, ConstantInt::get(Ty, Together));
2512 const APInt *ShiftC;
2514 ShiftC->
ult(Width)) {
2519 Constant *ShAmtC = ConstantInt::get(Ty, ShiftC->
zext(Width));
2520 return BinaryOperator::CreateLShr(Sext, ShAmtC);
2528 return BinaryOperator::CreateLShr(
X, ConstantInt::get(Ty, *ShiftC));
2536 if (Op0->
hasOneUse() &&
C->isPowerOf2() && (*AddC & (*
C - 1)) == 0) {
2537 assert((*
C & *AddC) != 0 &&
"Expected common bit");
2539 return BinaryOperator::CreateXor(NewAnd, Op1);
2546 switch (
B->getOpcode()) {
2547 case Instruction::Xor:
2548 case Instruction::Or:
2549 case Instruction::Mul:
2550 case Instruction::Add:
2551 case Instruction::Sub:
2567 C->isIntN(
X->getType()->getScalarSizeInBits())) {
2568 unsigned XWidth =
X->getType()->getScalarSizeInBits();
2569 Constant *TruncC1 = ConstantInt::get(
X->getType(), C1->
trunc(XWidth));
2573 Constant *TruncC = ConstantInt::get(
X->getType(),
C->trunc(XWidth));
2583 C->isMask(
X->getType()->getScalarSizeInBits())) {
2593 C->isMask(
X->getType()->getScalarSizeInBits())) {
2627 if (
C->isPowerOf2() &&
2630 int Log2C =
C->exactLogBase2();
2632 cast<BinaryOperator>(Op0)->getOpcode() == Instruction::Shl;
2633 int BitNum = IsShiftLeft ? Log2C - Log2ShiftC : Log2ShiftC - Log2C;
2634 assert(BitNum >= 0 &&
"Expected demanded bits to handle impossible mask");
2667 if (Cmp && Cmp->isZeroValue()) {
2692 Attribute::NoImplicitFloat)) {
2709 X->getType()->getScalarSizeInBits())))) {
2711 return BinaryOperator::CreateAnd(SExt, Op1);
2717 if (
I.getType()->isIntOrIntVectorTy(1)) {
2718 if (
auto *SI0 = dyn_cast<SelectInst>(Op0)) {
2720 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
true))
2723 if (
auto *SI1 = dyn_cast<SelectInst>(Op1)) {
2725 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
true))
2740 return BinaryOperator::CreateAnd(Op0,
B);
2743 return BinaryOperator::CreateAnd(Op1,
B);
2751 if (NotC !=
nullptr)
2752 return BinaryOperator::CreateAnd(Op0, NotC);
2761 if (NotC !=
nullptr)
2771 return BinaryOperator::CreateAnd(
A,
B);
2779 return BinaryOperator::CreateAnd(
A,
B);
2799 foldBooleanAndOr(Op0, Op1,
I,
true,
false))
2803 bool IsLogical = isa<SelectInst>(Op1);
2804 if (
auto *V = reassociateBooleanAndOr(Op0,
X,
Y,
I,
true,
2809 bool IsLogical = isa<SelectInst>(Op0);
2810 if (
auto *V = reassociateBooleanAndOr(Op1,
X,
Y,
I,
true,
2818 if (
Instruction *CastedAnd = foldCastedBitwiseLogic(
I))
2831 A->getType()->isIntOrIntVectorTy(1))
2837 A->getType()->isIntOrIntVectorTy(1))
2842 A->getType()->isIntOrIntVectorTy(1))
2849 if (
A->getType()->isIntOrIntVectorTy(1))
2862 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2871 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2882 Value *Start =
nullptr, *Step =
nullptr;
2890 return Canonicalized;
2892 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
2904 return BinaryOperator::CreateAnd(V, Op1);
2908 return BinaryOperator::CreateAnd(Op0, V);
2915 bool MatchBitReversals) {
2923 for (
auto *Inst : Insts) {
2924 Inst->setDebugLoc(
I.getDebugLoc());
2930std::optional<std::pair<Intrinsic::ID, SmallVector<Value *, 3>>>
2934 assert(
Or.getOpcode() == BinaryOperator::Or &&
"Expecting or instruction");
2936 unsigned Width =
Or.getType()->getScalarSizeInBits();
2941 return std::nullopt;
2948 if (isa<BinaryOperator>(Or0) && isa<BinaryOperator>(Or1)) {
2949 Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
2955 return std::nullopt;
2958 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2964 Or1->
getOpcode() == BinaryOperator::LShr &&
2965 "Illegal or(shift,shift) pair");
2969 auto matchShiftAmount = [&](
Value *L,
Value *R,
unsigned Width) ->
Value * {
2971 const APInt *LI, *RI;
2973 if (LI->
ult(Width) && RI->
ult(Width) && (*LI + *RI) == Width)
2974 return ConstantInt::get(L->getType(), *LI);
2998 if (ShVal0 != ShVal1)
3009 unsigned Mask = Width - 1;
3033 Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, Width);
3035 ShAmt = matchShiftAmount(ShAmt1, ShAmt0, Width);
3039 return std::nullopt;
3041 FShiftArgs = {ShVal0, ShVal1, ShAmt};
3042 }
else if (isa<ZExtInst>(Or0) || isa<ZExtInst>(Or1)) {
3054 if (!isa<ZExtInst>(Or1))
3058 const APInt *ZextHighShlAmt;
3061 return std::nullopt;
3065 return std::nullopt;
3067 unsigned HighSize =
High->getType()->getScalarSizeInBits();
3068 unsigned LowSize =
Low->getType()->getScalarSizeInBits();
3071 if (ZextHighShlAmt->
ult(LowSize) || ZextHighShlAmt->
ugt(Width - HighSize))
3072 return std::nullopt;
3079 if (!isa<ZExtInst>(
Y))
3082 const APInt *ZextLowShlAmt;
3089 if (*ZextLowShlAmt + *ZextHighShlAmt != Width)
3095 ZextLowShlAmt->
ule(Width - LowSize) &&
"Invalid concat");
3097 FShiftArgs = {U, U, ConstantInt::get(Or0->
getType(), *ZextHighShlAmt)};
3102 if (FShiftArgs.
empty())
3103 return std::nullopt;
3105 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
3106 return std::make_pair(IID, FShiftArgs);
3112 auto [IID, FShiftArgs] = *Opt;
3123 assert(
Or.getOpcode() == Instruction::Or &&
"bswap requires an 'or'");
3124 Value *Op0 =
Or.getOperand(0), *Op1 =
Or.getOperand(1);
3128 if ((Width & 1) != 0)
3130 unsigned HalfWidth = Width / 2;
3133 if (!isa<ZExtInst>(Op0))
3137 Value *LowerSrc, *ShlVal, *UpperSrc;
3150 NewUpper = Builder.
CreateShl(NewUpper, HalfWidth);
3157 Value *LowerBSwap, *UpperBSwap;
3160 return ConcatIntrinsicCalls(Intrinsic::bswap, UpperBSwap, LowerBSwap);
3164 Value *LowerBRev, *UpperBRev;
3167 return ConcatIntrinsicCalls(Intrinsic::bitreverse, UpperBRev, LowerBRev);
3186 unsigned NumElts = cast<FixedVectorType>(C1->
getType())->getNumElements();
3187 for (
unsigned i = 0; i != NumElts; ++i) {
3190 if (!EltC1 || !EltC2)
3209 Type *Ty =
A->getType();
3225 if (
A->getType()->isIntOrIntVectorTy()) {
3227 if (NumSignBits ==
A->getType()->getScalarSizeInBits() &&
3250 Cond->getType()->isIntOrIntVectorTy(1)) {
3276 Cond->getType()->isIntOrIntVectorTy(1) &&
3290 Value *
D,
bool InvertFalseVal) {
3293 Type *OrigType =
A->getType();
3296 if (
Value *
Cond = getSelectCondition(
A,
C, InvertFalseVal)) {
3301 Type *SelTy =
A->getType();
3302 if (
auto *VecTy = dyn_cast<VectorType>(
Cond->getType())) {
3304 unsigned Elts = VecTy->getElementCount().getKnownMinValue();
3325 bool IsAnd,
bool IsLogical,
3332 IsAnd ?
LHS->getInversePredicate() :
LHS->getPredicate();
3334 IsAnd ?
RHS->getInversePredicate() :
RHS->getPredicate();
3343 auto MatchRHSOp = [LHS0, CInt](
const Value *RHSOp) {
3346 (CInt->
isZero() && RHSOp == LHS0);
3375 Value *LHS0 =
LHS->getOperand(0), *RHS0 =
RHS->getOperand(0);
3376 Value *LHS1 =
LHS->getOperand(1), *RHS1 =
RHS->getOperand(1);
3378 const APInt *LHSC =
nullptr, *RHSC =
nullptr;
3385 if (LHS0 == RHS1 && LHS1 == RHS0) {
3389 if (LHS0 == RHS0 && LHS1 == RHS1) {
3392 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
3415 RHS->setSameSign(
false);
3441 if (IsAnd && !IsLogical)
3498 const APInt *AndC, *SmallC =
nullptr, *BigC =
nullptr;
3512 if (SmallC && BigC) {
3513 unsigned BigBitSize = BigC->getBitWidth();
3532 bool TrueIfSignedL, TrueIfSignedR;
3538 if ((TrueIfSignedL && !TrueIfSignedR &&
3541 (!TrueIfSignedL && TrueIfSignedR &&
3548 if ((TrueIfSignedL && !TrueIfSignedR &&
3551 (!TrueIfSignedL && TrueIfSignedR &&
3564 if (LHS0 == RHS0 && PredL == PredR &&
3566 !
I.getFunction()->hasFnAttribute(Attribute::NoImplicitFloat) &&
3569 X->getType()->getScalarType()->isIEEELikeFPTy() &&
3570 APFloat(
X->getType()->getScalarType()->getFltSemantics(), *MaskC)
3572 ((LHSC->
isZero() && *RHSC == *MaskC) ||
3573 (RHSC->
isZero() && *LHSC == *MaskC)))
3577 return foldAndOrOfICmpsUsingRanges(LHS, RHS, IsAnd);
3595 if (
auto *LHSCmp = dyn_cast<ICmpInst>(LHS))
3596 if (
auto *RHSCmp = dyn_cast<ICmpInst>(RHS))
3597 if (
Value *Res = foldAndOrOfICmps(LHSCmp, RHSCmp,
I, IsAnd, IsLogical))
3600 if (
auto *LHSCmp = dyn_cast<FCmpInst>(LHS))
3601 if (
auto *RHSCmp = dyn_cast<FCmpInst>(RHS))
3602 if (
Value *Res = foldLogicOfFCmps(LHSCmp, RHSCmp, IsAnd, IsLogical))
3605 if (
Value *Res = foldEqOfParts(LHS, RHS, IsAnd))
3613 assert(
I.getOpcode() == Instruction::Or &&
3614 "Simplification only supports or at the moment.");
3616 Value *Cmp1, *Cmp2, *Cmp3, *Cmp4;
3648 auto *VecTy = dyn_cast<FixedVectorType>(Vec->
getType());
3651 auto *EltTy = dyn_cast<IntegerType>(VecTy->getElementType());
3655 const unsigned EltBitWidth = EltTy->getBitWidth();
3656 const unsigned TargetBitWidth = V->getType()->getIntegerBitWidth();
3657 if (TargetBitWidth % EltBitWidth != 0 || ShlAmt % EltBitWidth != 0)
3659 const unsigned TargetEltWidth = TargetBitWidth / EltBitWidth;
3660 const unsigned ShlEltAmt = ShlAmt / EltBitWidth;
3662 const unsigned MaskIdx =
3663 DL.isLittleEndian() ? ShlEltAmt : TargetEltWidth - ShlEltAmt - 1;
3665 VecOffset =
static_cast<int64_t
>(VecIdx) -
static_cast<int64_t
>(MaskIdx);
3666 Mask.resize(TargetEltWidth);
3676 auto *SrcTy = dyn_cast<FixedVectorType>(SrcVecI->
getType());
3680 Mask.resize(SrcTy->getNumElements());
3683 if (isa<ShuffleVectorInst>(SrcVecI)) {
3690 auto *VecTy = dyn_cast<FixedVectorType>(Vec->
getType());
3694 const unsigned NumVecElts = VecTy->getNumElements();
3695 bool FoundVecOffset =
false;
3699 const unsigned ShuffleIdx = ShuffleMask[
Idx];
3700 if (ShuffleIdx >= NumVecElts) {
3701 const unsigned ConstIdx = ShuffleIdx - NumVecElts;
3704 if (!ConstElt || !ConstElt->isNullValue())
3709 if (FoundVecOffset) {
3710 if (VecOffset +
Idx != ShuffleIdx)
3713 if (ShuffleIdx <
Idx)
3715 VecOffset = ShuffleIdx -
Idx;
3716 FoundVecOffset =
true;
3720 return FoundVecOffset;
3729 auto *VecTy = dyn_cast<FixedVectorType>(Vec->
getType());
3733 bool AlreadyInsertedMaskedElt = Mask.test(InsertIdx);
3735 if (!AlreadyInsertedMaskedElt)
3736 Mask.reset(InsertIdx);
3745 assert(
I.getOpcode() == Instruction::Or);
3746 Value *LhsVec, *RhsVec;
3747 int64_t LhsVecOffset, RhsVecOffset;
3755 if (LhsVec != RhsVec || LhsVecOffset != RhsVecOffset)
3759 const unsigned ZeroVecIdx =
3760 cast<FixedVectorType>(LhsVec->
getType())->getNumElements();
3762 for (
unsigned Idx : Mask.set_bits()) {
3764 ShuffleMask[
Idx] = LhsVecOffset +
Idx;
3769 I.getName() +
".v");
3787 IsShlNUW = cast<BinaryOperator>(V)->hasNoUnsignedWrap();
3788 IsShlNSW = cast<BinaryOperator>(V)->hasNoSignedWrap();
3795 const APInt *ShiftedMaskConst =
nullptr;
3802 if (!
match(MaskedOp0,
3807 if (LShrAmt > ShlAmt)
3809 Offset = ShlAmt - LShrAmt;
3811 Mask = ShiftedMaskConst ? ShiftedMaskConst->
shl(LShrAmt)
3813 Int->getType()->getScalarSizeInBits(), LShrAmt);
3823 Value *LhsInt, *RhsInt;
3824 APInt LhsMask, RhsMask;
3826 bool IsLhsShlNUW, IsLhsShlNSW, IsRhsShlNUW, IsRhsShlNSW;
3833 if (LhsInt != RhsInt || LhsOffset != RhsOffset)
3836 APInt Mask = LhsMask | RhsMask;
3843 ConstantInt::get(DestTy, LhsOffset),
"", IsLhsShlNUW && IsRhsShlNUW,
3844 IsLhsShlNSW && IsRhsShlNSW);
3861 return X ==
Other.X && !Mask.intersects(
Other.Mask) &&
3862 Factor ==
Other.Factor;
3869 return std::nullopt;
3872 Value *Original =
nullptr;
3873 const APInt *Mask =
nullptr;
3874 const APInt *MulConst =
nullptr;
3877 if (MulConst->
isZero() || Mask->isZero())
3878 return std::nullopt;
3880 return std::optional<DecomposedBitMaskMul>(
3881 {Original, *MulConst, *Mask,
3882 cast<BinaryOperator>(
Op)->hasNoUnsignedWrap(),
3883 cast<BinaryOperator>(
Op)->hasNoSignedWrap()});
3887 const APInt *EqZero =
nullptr, *NeZero =
nullptr;
3891 auto ICmpDecompose =
3894 if (!ICmpDecompose.has_value())
3895 return std::nullopt;
3898 ICmpDecompose->C.isZero());
3903 if (!EqZero->
isZero() || NeZero->isZero())
3904 return std::nullopt;
3906 if (!ICmpDecompose->Mask.isPowerOf2() || ICmpDecompose->Mask.isZero() ||
3907 NeZero->getBitWidth() != ICmpDecompose->Mask.getBitWidth())
3908 return std::nullopt;
3910 if (!NeZero->urem(ICmpDecompose->Mask).isZero())
3911 return std::nullopt;
3913 return std::optional<DecomposedBitMaskMul>(
3914 {ICmpDecompose->X, NeZero->udiv(ICmpDecompose->Mask),
3915 ICmpDecompose->Mask,
false,
false});
3918 return std::nullopt;
3934 if (Decomp0->isCombineableWith(*Decomp1)) {
3937 ConstantInt::get(Decomp0->X->getType(), Decomp0->Mask + Decomp1->Mask));
3940 NewAnd, ConstantInt::get(NewAnd->
getType(), Decomp1->Factor),
"",
3941 Decomp0->NUW && Decomp1->NUW, Decomp0->NSW && Decomp1->NSW);
3956Value *InstCombinerImpl::reassociateDisjointOr(
Value *LHS,
Value *RHS) {
3960 if (
Value *Res = foldDisjointOr(LHS,
X))
3962 if (
Value *Res = foldDisjointOr(LHS,
Y))
3967 if (
Value *Res = foldDisjointOr(
X, RHS))
3969 if (
Value *Res = foldDisjointOr(
Y, RHS))
3984 const APInt *C1, *C2;
3986 m_c_Or(m_ExtractValue<1>(
3987 m_Value(WOV, m_Intrinsic<Intrinsic::umul_with_overflow>(
3993 Constant *NewC = ConstantInt::get(
X->getType(), C2->
udiv(*C1));
4040 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
4041 Type *Ty =
I.getType();
4043 if (
auto *SI0 = dyn_cast<SelectInst>(Op0)) {
4045 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
false))
4048 if (
auto *SI1 = dyn_cast<SelectInst>(Op1)) {
4050 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
false))
4074 if (cast<PossiblyDisjointInst>(
I).isDisjoint()) {
4084 if (
Value *Res = foldDisjointOr(
I.getOperand(0),
I.getOperand(1)))
4087 if (
Value *Res = reassociateDisjointOr(
I.getOperand(0),
I.getOperand(1)))
4098 return BinaryOperator::CreateXor(
Or, ConstantInt::get(Ty, *CV));
4106 return BinaryOperator::CreateMul(
X, IncrementY);
4115 const APInt *C0, *C1;
4134 if ((*C0 & *C1).
isZero()) {
4139 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
4140 return BinaryOperator::CreateAnd(
A, C01);
4146 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
4147 return BinaryOperator::CreateAnd(
B, C01);
4151 const APInt *C2, *C3;
4156 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
4157 return BinaryOperator::CreateAnd(
Or, C01);
4167 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D))
4169 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B))
4171 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D))
4173 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B))
4175 if (
Value *V = matchSelectFromAndOr(
B,
D,
A,
C))
4177 if (
Value *V = matchSelectFromAndOr(
B,
D,
C,
A))
4179 if (
Value *V = matchSelectFromAndOr(
D,
B,
A,
C))
4181 if (
Value *V = matchSelectFromAndOr(
D,
B,
C,
A))
4190 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D,
true))
4192 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B,
true))
4194 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D,
true))
4196 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B,
true))
4205 return BinaryOperator::CreateOr(Op0,
C);
4212 return BinaryOperator::CreateOr(Op1,
C);
4218 bool SwappedForXor =
false;
4221 SwappedForXor =
true;
4228 return BinaryOperator::CreateOr(Op0,
B);
4230 return BinaryOperator::CreateOr(Op0,
A);
4235 return BinaryOperator::CreateOr(
A,
B);
4263 return BinaryOperator::CreateOr(Nand,
C);
4271 foldBooleanAndOr(Op0, Op1,
I,
false,
false))
4275 bool IsLogical = isa<SelectInst>(Op1);
4276 if (
auto *V = reassociateBooleanAndOr(Op0,
X,
Y,
I,
false,
4281 bool IsLogical = isa<SelectInst>(Op0);
4282 if (
auto *V = reassociateBooleanAndOr(Op1,
X,
Y,
I,
false,
4302 A->getType()->isIntOrIntVectorTy(1))
4319 bool IsDisjointOuter = cast<PossiblyDisjointInst>(
I).isDisjoint();
4320 bool IsDisjointInner = cast<PossiblyDisjointInst>(Op0)->isDisjoint();
4322 cast<PossiblyDisjointInst>(Inner)->setIsDisjoint(IsDisjointOuter);
4324 return IsDisjointOuter && IsDisjointInner
4325 ? BinaryOperator::CreateDisjointOr(Inner, CI)
4326 : BinaryOperator::CreateOr(Inner, CI);
4333 Value *
X =
nullptr, *
Y =
nullptr;
4365 return BinaryOperator::CreateXor(
A,
B);
4381 Value *
Mul, *Ov, *MulIsNotZero, *UMulWithOv;
4395 if (
match(UMulWithOv, m_Intrinsic<Intrinsic::umul_with_overflow>(
4399 return BinaryOperator::CreateAnd(NotNullA, NotNullB);
4408 const APInt *C1, *C2;
4423 : C2->
uadd_ov(*C1, Overflow));
4427 return BinaryOperator::CreateOr(Ov, NewCmp);
4452 Value *Start =
nullptr, *Step =
nullptr;
4470 return BinaryOperator::CreateOr(
4482 return BinaryOperator::CreateOr(
4490 return Canonicalized;
4492 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
4513 Attribute::NoImplicitFloat)) {
4527 if ((KnownX.
One & *C2) == *C2)
4528 return BinaryOperator::CreateAnd(
X, ConstantInt::get(Ty, *C1 | *C2));
4537 return BinaryOperator::CreateOr(V, Op1);
4541 return BinaryOperator::CreateOr(Op0, V);
4543 if (cast<PossiblyDisjointInst>(
I).isDisjoint())
4554 assert(
I.getOpcode() == Instruction::Xor);
4555 Value *Op0 =
I.getOperand(0);
4556 Value *Op1 =
I.getOperand(1);
4567 return BinaryOperator::CreateXor(
A,
B);
4575 return BinaryOperator::CreateXor(
A,
B);
4583 return BinaryOperator::CreateXor(
A,
B);
4605 assert(
I.getOpcode() == Instruction::Xor &&
I.getOperand(0) == LHS &&
4606 I.getOperand(1) == RHS &&
"Should be 'xor' with these operands");
4609 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
4610 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
4613 if (LHS0 == RHS1 && LHS1 == RHS0) {
4617 if (LHS0 == RHS0 && LHS1 == RHS1) {
4620 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
4625 const APInt *LC, *RC;
4634 bool TrueIfSignedL, TrueIfSignedR;
4650 if (CRUnion && CRIntersect)
4651 if (
auto CR = CRUnion->exactIntersectWith(CRIntersect->inverse())) {
4652 if (CR->isFullSet())
4654 if (CR->isEmptySet())
4659 CR->getEquivalentICmp(NewPred, NewC,
Offset);
4668 ConstantInt::get(Ty, NewC));
4701 if (OrICmp == LHS && AndICmp == RHS) {
4706 if (OrICmp == RHS && AndICmp == LHS) {
4713 Y->setPredicate(
Y->getInversePredicate());
4715 if (!
Y->hasOneUse()) {
4726 Y->replaceUsesWithIf(NotY,
4727 [NotY](
Use &U) {
return U.getUser() != NotY; });
4766 return BinaryOperator::CreateXor(NewA,
X);
4772 Type *EltTy =
C->getType()->getScalarType();
4778 return BinaryOperator::CreateOr(
LHS,
RHS);
4793 return A ==
C ||
A ==
D ||
B ==
C ||
B ==
D;
4802 return BinaryOperator::CreateOr(
X, NotY);
4810 return BinaryOperator::CreateOr(
Y, NotX);
4820 assert(
Xor.getOpcode() == Instruction::Xor &&
"Expected an xor instruction.");
4826 Value *Op0 =
Xor.getOperand(0), *Op1 =
Xor.getOperand(1);
4841 auto *
Add = cast<BinaryOperator>(Op0);
4842 Value *NegA =
Add->hasNoUnsignedWrap()
4852 auto *
I = dyn_cast<Instruction>(
Op);
4859 auto *
I = cast<Instruction>(
Op);
4862 Op->replaceUsesWithIf(NotOp,
4863 [NotOp](
Use &U) {
return U.getUser() != NotOp; });
4891 bool IsBinaryOp = isa<BinaryOperator>(
I);
4931 bool IsBinaryOp = isa<BinaryOperator>(
I);
4933 Value *NotOp0 =
nullptr;
4934 Value *NotOp1 =
nullptr;
4935 Value **OpToInvert =
nullptr;
4980 Type *Ty =
I.getType();
4984 return BinaryOperator::CreateOr(
X, NotY);
4995 return BinaryOperator::CreateAnd(
X, NotY);
5010 return BinaryOperator::CreateAnd(DecX, NotY);
5015 return BinaryOperator::CreateAShr(
X,
Y);
5021 return BinaryOperator::CreateAShr(
X,
Y);
5077 Type *SextTy = cast<BitCastOperator>(NotOp)->getSrcTy();
5083 if (
auto *NotOpI = dyn_cast<Instruction>(NotOp))
5090 auto *
II = dyn_cast<IntrinsicInst>(NotOp);
5091 if (
II &&
II->hasOneUse()) {
5099 if (
II->getIntrinsicID() == Intrinsic::is_fpclass) {
5100 ConstantInt *ClassMask = cast<ConstantInt>(
II->getArgOperand(1));
5102 1, ConstantInt::get(ClassMask->
getType(),
5117 if (
auto *Sel = dyn_cast<SelectInst>(NotOp)) {
5118 Value *TV = Sel->getTrueValue();
5119 Value *FV = Sel->getFalseValue();
5120 auto *CmpT = dyn_cast<CmpInst>(TV);
5121 auto *CmpF = dyn_cast<CmpInst>(FV);
5122 bool InvertibleT = (CmpT && CmpT->hasOneUse()) || isa<Constant>(TV);
5123 bool InvertibleF = (CmpF && CmpF->hasOneUse()) || isa<Constant>(FV);
5124 if (InvertibleT && InvertibleF) {
5126 CmpT->setPredicate(CmpT->getInversePredicate());
5130 CmpF->setPredicate(CmpF->getInversePredicate());
5184 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5192 return BinaryOperator::CreateXor(XorAC,
Y);
5195 return BinaryOperator::CreateXor(XorBC,
X);
5205 return BinaryOperator::CreateDisjointOr(Op0, Op1);
5207 return BinaryOperator::CreateOr(Op0, Op1);
5224 return BinaryOperator::CreateXor(
5247 *CA ==
X->getType()->getScalarSizeInBits() - 1 &&
5255 Type *Ty =
I.getType();
5263 return BinaryOperator::CreateSub(ConstantInt::get(Ty, *
C + *RHSC),
X);
5267 return BinaryOperator::CreateAdd(
X, ConstantInt::get(Ty, *
C + *RHSC));
5272 return BinaryOperator::CreateXor(
X, ConstantInt::get(Ty, *
C ^ *RHSC));
5277 auto *
II = dyn_cast<IntrinsicInst>(Op0);
5280 if ((IID == Intrinsic::ctlz || IID == Intrinsic::cttz) &&
5283 IID = (IID == Intrinsic::ctlz) ? Intrinsic::cttz : Intrinsic::ctlz;
5296 return BinaryOperator::CreateShl(NotX, ConstantInt::get(Ty, *
C));
5302 return BinaryOperator::CreateLShr(NotX, ConstantInt::get(Ty, *
C));
5321 Attribute::NoImplicitFloat)) {
5346 return BinaryOperator::CreateXor(Opnd0, ConstantInt::get(Ty, FoldConst));
5379 return BinaryOperator::CreateXor(
5385 return BinaryOperator::CreateXor(
5391 return BinaryOperator::CreateOr(
A,
B);
5395 return BinaryOperator::CreateOr(
A,
B);
5405 return BinaryOperator::CreateOr(
A,
B);
5420 if (
B ==
C ||
B ==
D)
5431 if (
I.getType()->isIntOrIntVectorTy(1) &&
5434 bool NeedFreeze = isa<SelectInst>(Op0) && isa<SelectInst>(Op1) &&
B ==
D;
5435 if (
B ==
C ||
B ==
D)
5447 if (
auto *
LHS = dyn_cast<ICmpInst>(
I.getOperand(0)))
5448 if (
auto *
RHS = dyn_cast<ICmpInst>(
I.getOperand(1)))
5452 if (
Instruction *CastedXor = foldCastedBitwiseLogic(
I))
5471 return Canonicalized;
5473 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
5476 if (
Instruction *Folded = canonicalizeConditionalNegationViaMathToSelect(
I))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
std::optional< std::vector< StOtherPiece > > Other
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 Value * foldBitmaskMul(Value *Op0, Value *Op1, InstCombiner::BuilderTy &Builder)
(A & N) * C + (A & M) * C -> (A & (N + M)) & C This also accepts the equivalent select form of (A & N...
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 Value * foldLogOpOfMaskedICmps(Value *LHS, Value *RHS, bool IsAnd, bool IsLogical, InstCombiner::BuilderTy &Builder, const SimplifyQuery &Q)
Try to fold (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E) into a single (icmp(A & X) ==/!...
static Value * getFCmpValue(unsigned Code, Value *LHS, Value *RHS, InstCombiner::BuilderTy &Builder, FMFSource FMF)
This is the complement of getFCmpCode, which turns an opcode and two operands into either a FCmp inst...
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 Value * foldLogOpOfMaskedICmpsAsymmetric(Value *LHS, Value *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 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 * foldOrUnsignedUMulOverflowICmp(BinaryOperator &I, InstCombiner::BuilderTy &Builder, const DataLayout &DL)
Fold Res, Overflow = (umul.with.overflow x c1); (or Overflow (ugt Res c2)) --> (ugt x (c2/c1)).
static Value * freelyInvert(InstCombinerImpl &IC, Value *Op, Instruction *IgnoredUser)
static Value * foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(Value *LHS, Value *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 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 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 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 bool matchZExtedSubInteger(Value *V, Value *&Int, APInt &Mask, uint64_t &Offset, bool &IsShlNUW, bool &IsShlNSW)
Match V as "lshr -> mask -> zext -> shl".
static std::optional< DecomposedBitMaskMul > matchBitmaskMul(Value *V)
static Value * foldOrOfInversions(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static bool matchSubIntegerPackFromVector(Value *V, Value *&Vec, int64_t &VecOffset, SmallBitVector &Mask, const DataLayout &DL)
Match V as "shufflevector -> bitcast" or "extractelement -> zext -> shl" patterns,...
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 * matchOrConcat(Instruction &Or, InstCombiner::BuilderTy &Builder)
Attempt to combine or(zext(x),shl(zext(y),bw/2) concat packing patterns.
static Value * foldAndOrOfICmpsWithPow2AndWithZero(InstCombiner::BuilderTy &Builder, ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, const SimplifyQuery &Q)
static Instruction * foldBitwiseLogicWithIntrinsics(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static std::optional< std::pair< unsigned, unsigned > > getMaskedTypeForICmpPair(Value *&A, Value *&B, Value *&C, Value *&D, Value *&E, Value *LHS, Value *RHS, ICmpInst::Predicate &PredL, ICmpInst::Predicate &PredR)
Handle (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E).
static Instruction * foldIntegerPackFromVector(Instruction &I, InstCombiner::BuilderTy &Builder, const DataLayout &DL)
Try to fold the join of two scalar integers whose contents are packed elements of the same vector.
static Value * foldIntegerRepackThroughZExt(Value *Lhs, Value *Rhs, InstCombiner::BuilderTy &Builder)
Try to fold the join of two scalar integers whose bits are unpacked and zexted from the same source i...
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
This file implements the SmallBitVector class.
static constexpr int Concat[]
support::ulittle16_t & Lo
support::ulittle16_t & Hi
bool bitwiseIsEqual(const APFloat &RHS) const
bool isPosInfinity() const
APInt bitcastToAPInt() const
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
Class for arbitrary precision integers.
LLVM_ABI APInt udiv(const APInt &RHS) const
Unsigned division operation.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
APInt abs() const
Get the absolute value.
unsigned countLeadingOnes() const
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
LLVM_ABI APInt usub_ov(const APInt &RHS, bool &Overflow) const
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isSignMask() const
Check if the APInt's value is returned by getSignMask.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
LLVM_ABI 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
LLVM_ABI APInt reverseBits() const
LLVM_ABI 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.
LLVM_ABI APInt byteSwap() const
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.
LLVM_ABI APInt ssub_ov(const APInt &RHS, bool &Overflow) const
static APInt getBitsSetFrom(unsigned numBits, unsigned loBit)
Constructs an APInt value that has a contiguous range of bits set.
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_ABI bool isSigned() const
Whether the intrinsic is signed or unsigned.
LLVM_ABI Instruction::BinaryOps getBinaryOp() const
Returns the binary operation underlying the intrinsic.
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
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 LLVM_ABI 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 LLVM_ABI 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 LLVM_ABI Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI Constant * getNot(Constant *C)
static LLVM_ABI Constant * getXor(Constant *C1, Constant *C2)
static LLVM_ABI Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI 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 LLVM_ABI 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 LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
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.
LLVM_ABI std::optional< ConstantRange > exactUnionWith(const ConstantRange &CR) const
Union the two ranges and return the result if it can be represented exactly, otherwise return std::nu...
LLVM_ABI 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.
LLVM_ABI 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 LLVM_ABI ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)
Produce the exact range such that all values in the returned range satisfy the given predicate with a...
LLVM_ABI 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 LLVM_ABI Constant * replaceUndefsWith(Constant *C, Constant *Replacement)
Try to replace undefined constant C or undefined elements in C with Replacement.
static LLVM_ABI Constant * mergeUndefsWith(Constant *C, Constant *Other)
Merges undefs of a Constant with another Constant, along with the undefs already present.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
LLVM_ABI bool isZeroValue() const
Return true if the value is negative zero or null value.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
LLVM_ABI 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.
This provides a helper for copying FMF from an instruction or setting specified flags.
static FMFSource intersect(Value *A, Value *B)
Intersect the FMF from two instructions.
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.
Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")
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.
LLVM_ABI 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 * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="", MDNode *FPMathTag=nullptr, FMFSource FMFSource={})
Value * CreateIsNotNeg(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg > -1.
BasicBlock * GetInsertBlock() const
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateFCmpFMF(CmpInst::Predicate P, Value *LHS, Value *RHS, FMFSource FMFSource, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
LLVM_ABI Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 2 operands which is mangled on the first type.
LLVM_ABI Value * createIsFPClass(Value *FPNum, unsigned Test)
LLVM_ABI CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
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="")
LLVM_ABI CallInst * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 1 operand which is mangled on its type.
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 * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
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 * 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)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
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).
unsigned ComputeNumSignBits(const Value *Op, const Instruction *CxtI=nullptr, unsigned Depth=0) const
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
InstructionWorklist & Worklist
A worklist of the instructions that need to be simplified.
void computeKnownBits(const Value *V, KnownBits &Known, const Instruction *CxtI, unsigned Depth=0) 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)
bool MaskedValueIsZero(const Value *V, const APInt &Mask, const Instruction *CxtI=nullptr, unsigned Depth=0) const
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
const SimplifyQuery & getSimplifyQuery() const
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, const Instruction *CxtI=nullptr, unsigned Depth=0)
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.
LLVM_ABI 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 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
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.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
LLVM_ABI const fltSemantics & getFltSemantics() const
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isIEEELikeFPTy() const
Return true if this is a well-behaved IEEE-like type, which has a IEEE compatible layout,...
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()
LLVM_ABI bool hasNUsesOrMore(unsigned N) const
Return true if this value has N uses or more.
LLVM_ABI bool hasNUses(unsigned N) const
Return true if this Value has exactly N uses.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
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.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
cst_pred_ty< is_lowbit_mask > m_LowBitMask()
Match an integer or vector with only the low bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
cst_pred_ty< is_negative > m_Negative()
Match an integer or vector of negative values.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
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.
TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)
Matches ExtractElementInst.
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.
ShiftLike_match< LHS, Instruction::Shl > m_ShlOrSelf(const LHS &L, uint64_t &R)
Matches shl L, ConstShAmt or L itself (R will be set to zero in this case).
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.
SpecificCmpClass_match< LHS, RHS, CmpInst > m_SpecificCmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
apint_match m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
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.
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
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< 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.
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
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.
LLVM_ABI 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.
LLVM_ABI bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS, bool &TrueIfSigned)
Given an exploded icmp instruction, return true if the comparison only checks the sign bit.
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...
LLVM_ABI Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Instruction *I=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
LLVM_ABI Value * simplifyOrInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an Or, fold the result or return null.
LLVM_ABI Value * simplifyXorInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an Xor, fold the result or return null.
LLVM_ABI 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.
LLVM_ABI 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,...
LLVM_ABI bool isKnownNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the given value is known be negative (i.e.
LLVM_ABI 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.
LLVM_ABI Value * simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an ICmpInst, fold the result or return null.
LLVM_ABI Value * simplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an And, fold the result or return null.
LLVM_ABI bool isKnownInversion(const Value *X, const Value *Y)
Return true iff:
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
constexpr int PoisonMaskElem
LLVM_ABI Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
std::optional< DecomposedBitTest > decomposeBitTest(Value *Cond, bool LookThroughTrunc=true, bool AllowNonZeroC=false, bool DecomposeAnd=false)
Decompose an icmp into the form ((X & Mask) pred C) if possible.
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
LLVM_ABI 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
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.
LLVM_ABI bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Return true if the given value is known to have exactly one bit set when defined.
LLVM_ABI 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.
std::pair< Value *, FPClassTest > fcmpToClassTest(FCmpInst::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...
unsigned getFCmpCode(CmpInst::Predicate CC)
Similar to getICmpCode but for FCmpInst.
std::optional< DecomposedBitTest > decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate Pred, bool LookThroughTrunc=true, bool AllowNonZeroC=false, bool DecomposeAnd=false)
Decompose an icmp into the form ((X & Mask) pred C) if possible.
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 isCombineableWith(const DecomposedBitMaskMul Other)
static LLVM_ABI bool hasSignBitInMSB(const fltSemantics &)
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