23using namespace PatternMatch;
25#define DEBUG_TYPE "instcombine"
56 "Lo is not < Hi in range emission code!");
58 Type *Ty = V->getType();
63 if (
isSigned ?
Lo.isMinSignedValue() :
Lo.isMinValue()) {
120 const APInt *ConstA =
nullptr, *ConstB =
nullptr, *ConstC =
nullptr;
125 bool IsAPow2 = ConstA && ConstA->
isPowerOf2();
126 bool IsBPow2 = ConstB && ConstB->isPowerOf2();
127 unsigned MaskVal = 0;
128 if (ConstC && ConstC->isZero()) {
147 }
else if (ConstA && ConstC && ConstC->
isSubsetOf(*ConstA)) {
157 }
else if (ConstB && ConstC && ConstC->isSubsetOf(*ConstB)) {
188 Y = ConstantInt::get(
X->getType(), Mask);
189 Z = ConstantInt::get(
X->getType(), 0);
214 Value *L11, *L12, *L21, *L22;
217 L21 = L22 = L1 =
nullptr;
242 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
245 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
262 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
267 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
286 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
291 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
300 assert(Ok &&
"Failed to find AND on the right side of the RHS icmp.");
306 }
else if (L12 ==
A) {
309 }
else if (L21 ==
A) {
312 }
else if (L22 ==
A) {
319 return std::optional<std::pair<unsigned, unsigned>>(
320 std::make_pair(LeftType, RightType));
342 const APInt *BCst, *CCst, *DCst, *OrigECst;
353 APInt ECst = *OrigECst;
359 if (*BCst == 0 || *DCst == 0)
366 if ((*BCst & *DCst) == 0)
385 if ((((*BCst & *DCst) & ECst) == 0) &&
386 (*BCst & (*BCst ^ *DCst)).isPowerOf2()) {
387 APInt BorD = *BCst | *DCst;
388 APInt BandBxorDorE = (*BCst & (*BCst ^ *DCst)) | ECst;
389 Value *NewMask = ConstantInt::get(
A->getType(), BorD);
390 Value *NewMaskedValue = ConstantInt::get(
A->getType(), BandBxorDorE);
392 return Builder.
CreateICmp(NewCC, NewAnd, NewMaskedValue);
395 auto IsSubSetOrEqual = [](
const APInt *C1,
const APInt *C2) {
396 return (*C1 & *C2) == *C1;
398 auto IsSuperSetOrEqual = [](
const APInt *C1,
const APInt *C2) {
399 return (*C1 & *C2) == *C2;
408 if (!IsSubSetOrEqual(BCst, DCst) && !IsSuperSetOrEqual(BCst, DCst))
420 if (IsSubSetOrEqual(BCst, DCst))
421 return ConstantInt::get(
LHS->
getType(), !IsAnd);
431 if (IsSuperSetOrEqual(BCst, DCst))
436 assert(IsSubSetOrEqual(BCst, DCst) &&
"Precondition due to above code");
437 if ((*BCst & ECst) != 0)
443 return ConstantInt::get(
LHS->
getType(), !IsAnd);
455 "Expected equality predicates for masked type of icmps.");
468 PredL, PredR, Builder)) {
474 PredR, PredL, Builder)) {
486 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *
E =
nullptr;
488 std::optional<std::pair<unsigned, unsigned>> MaskPair =
493 "Expected equality predicates for masked type of icmps.");
494 unsigned LHSMask = MaskPair->first;
495 unsigned RHSMask = MaskPair->second;
496 unsigned Mask = LHSMask & RHSMask;
501 LHS,
RHS, IsAnd,
A,
B,
C,
D,
E, PredL, PredR, LHSMask, RHSMask,
537 return Builder.
CreateICmp(NewCC, NewAnd, Zero);
546 return Builder.
CreateICmp(NewCC, NewAnd, NewOr);
561 const APInt *ConstB, *ConstD;
571 APInt NewMask = *ConstB & *ConstD;
572 if (NewMask == *ConstB)
574 else if (NewMask == *ConstD)
583 APInt NewMask = *ConstB | *ConstD;
584 if (NewMask == *ConstB)
586 else if (NewMask == *ConstD)
613 const APInt *OldConstC, *OldConstE;
619 const APInt ConstC = PredL !=
CC ? *ConstB ^ *OldConstC : *OldConstC;
620 const APInt ConstE = PredR !=
CC ? *ConstD ^ *OldConstE : *OldConstE;
622 if (((*ConstB & *ConstD) & (ConstC ^ ConstE)).getBoolValue())
623 return IsNot ? nullptr : ConstantInt::get(
LHS->
getType(), !IsAnd);
625 if (IsNot && !ConstB->
isSubsetOf(*ConstD) && !ConstD->isSubsetOf(*ConstB))
630 BD = *ConstB & *ConstD;
631 CE = ConstC & ConstE;
633 BD = *ConstB | *ConstD;
634 CE = ConstC | ConstE;
637 Value *CEVal = ConstantInt::get(
A->getType(), CE);
642 return FoldBMixed(NewCC,
false);
644 return FoldBMixed(NewCC,
true);
690 default:
return nullptr;
706Value *InstCombinerImpl::foldAndOrOfICmpsOfAndWithPow2(
ICmpInst *LHS,
712 if (
LHS->getPredicate() != Pred ||
RHS->getPredicate() != Pred)
722 if (L1 ==
R2 || L2 ==
R2)
780 auto tryToMatchSignedTruncationCheck = [](
ICmpInst *ICmp,
Value *&
X,
781 APInt &SignBitMask) ->
bool {
783 const APInt *I01, *I1;
798 if (tryToMatchSignedTruncationCheck(ICmp1, X1, HighestBit))
800 else if (tryToMatchSignedTruncationCheck(ICmp0, X1, HighestBit))
805 assert(HighestBit.
isPowerOf2() &&
"expected to be power of two (non-zero)");
809 APInt &UnsetBitsMask) ->
bool {
813 Pred,
X, UnsetBitsMask,
821 UnsetBitsMask = *Mask;
830 if (!tryToDecompose(OtherICmp, X0, UnsetBitsMask))
833 assert(!UnsetBitsMask.
isZero() &&
"empty mask makes no sense.");
848 APInt SignBitsMask = ~(HighestBit - 1U);
855 if (!UnsetBitsMask.
isSubsetOf(SignBitsMask)) {
856 APInt OtherHighestBit = (~UnsetBitsMask) + 1U;
864 return Builder.
CreateICmpULT(
X, ConstantInt::get(
X->getType(), HighestBit),
865 CxtI.
getName() +
".simplified");
929 "Expected equality predicates for masked type of icmps.");
949 const APInt *BCst, *DCst, *ECst;
952 (isa<UndefValue>(
B) ||
957 if (
const auto *BVTy = dyn_cast<VectorType>(
B->getType())) {
958 const auto *BFVTy = dyn_cast<FixedVectorType>(BVTy);
959 const auto *BConst = dyn_cast<Constant>(
B);
960 const auto *DConst = dyn_cast<Constant>(
D);
961 const auto *EConst = dyn_cast<Constant>(
E);
963 if (!BFVTy || !BConst || !DConst || !EConst)
966 for (
unsigned I = 0;
I != BFVTy->getNumElements(); ++
I) {
967 const auto *BElt = BConst->getAggregateElement(
I);
968 const auto *DElt = DConst->getAggregateElement(
I);
969 const auto *EElt = EConst->getAggregateElement(
I);
971 if (!BElt || !DElt || !EElt)
973 if (!isReducible(BElt, DElt, EElt))
978 if (!isReducible(
B,
D,
E))
996 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *
E =
nullptr;
1002 std::optional<std::pair<unsigned, unsigned>> MaskPair =
1008 unsigned CmpMask0 = MaskPair->first;
1009 unsigned CmpMask1 = MaskPair->second;
1010 if ((CmpMask0 &
Mask_AllZeros) && (CmpMask1 == compareBMask)) {
1014 }
else if ((CmpMask0 == compareBMask) && (CmpMask1 &
Mask_AllZeros)) {
1025 ICmpInst *UnsignedICmp,
bool IsAnd,
1034 auto IsKnownNonZero = [&](
Value *V) {
1041 if (
match(UnsignedICmp,
1046 if (!IsKnownNonZero(NonZero))
1048 return IsKnownNonZero(NonZero);
1057 IsAnd && GetKnownNonZeroAndOther(
B,
A))
1060 !IsAnd && GetKnownNonZeroAndOther(
B,
A))
1077 return std::nullopt;
1079 unsigned NumOriginalBits =
X->getType()->getScalarSizeInBits();
1080 unsigned NumExtractedBits = V->getType()->getScalarSizeInBits();
1086 Shift->
ule(NumOriginalBits - NumExtractedBits))
1088 return {{
X, 0, NumExtractedBits}};
1096 Type *TruncTy = V->getType()->getWithNewBitWidth(
P.NumBits);
1097 if (TruncTy != V->getType())
1112 unsigned OpNo) -> std::optional<IntPart> {
1113 if (Pred ==
Cmp->getPredicate())
1122 return std::nullopt;
1131 return std::nullopt;
1133 return std::nullopt;
1138 return {{
I->getOperand(OpNo),
From,
C->getBitWidth() -
From}};
1141 std::optional<IntPart> L0 = GetMatchPart(Cmp0, 0);
1142 std::optional<IntPart> R0 = GetMatchPart(Cmp0, 1);
1143 std::optional<IntPart> L1 = GetMatchPart(Cmp1, 0);
1144 std::optional<IntPart> R1 = GetMatchPart(Cmp1, 1);
1145 if (!L0 || !R0 || !L1 || !R1)
1150 if (L0->From != L1->From || R0->From != R1->From) {
1151 if (L0->From != R1->From || R0->From != L1->From)
1158 if (L0->StartBit + L0->NumBits != L1->StartBit ||
1159 R0->StartBit + R0->NumBits != R1->StartBit) {
1160 if (L1->StartBit + L1->NumBits != L0->StartBit ||
1161 R1->StartBit + R1->NumBits != R0->StartBit)
1168 IntPart L = {L0->From, L0->StartBit, L0->NumBits + L1->NumBits};
1169 IntPart R = {R0->From, R0->StartBit, R0->NumBits + R1->NumBits};
1179 bool IsAnd,
bool IsLogical,
1208 if (!SubstituteCmp) {
1218 return Builder.
CreateBinOp(IsAnd ? Instruction::And : Instruction::Or, Cmp0,
1226Value *InstCombinerImpl::foldAndOrOfICmpsUsingRanges(
ICmpInst *ICmp1,
1231 const APInt *C1, *C2;
1238 const APInt *Offset1 =
nullptr, *Offset2 =
nullptr;
1273 if (!LowerDiff.
isPowerOf2() || LowerDiff != UpperDiff ||
1286 CR->getEquivalentICmp(NewPred, NewC,
Offset);
1318 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1319 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1328 FMF &=
RHS->getFastMathFlags();
1335 bool IsAnd,
bool IsLogicalSelect) {
1336 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1337 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1340 if (LHS0 == RHS1 && RHS0 == LHS1) {
1360 if (LHS0 == RHS0 && LHS1 == RHS1) {
1363 unsigned NewPred = IsAnd ? FCmpCodeL & FCmpCodeR : FCmpCodeL | FCmpCodeR;
1369 FMF &=
RHS->getFastMathFlags();
1376 if (!IsLogicalSelect &&
1407 auto [ClassValRHS, ClassMaskRHS] =
1410 auto [ClassValLHS, ClassMaskLHS] =
1412 if (ClassValLHS == ClassValRHS) {
1413 unsigned CombinedMask = IsAnd ? (ClassMaskLHS & ClassMaskRHS)
1414 : (ClassMaskLHS | ClassMaskRHS);
1416 Intrinsic::is_fpclass, {ClassValLHS->getType()},
1445 if (IsLessThanOrLessEqual(IsAnd ? PredR : PredL)) {
1449 if (IsLessThanOrLessEqual(IsAnd ? PredL : PredR)) {
1452 RHS->getFastMathFlags());
1456 ConstantFP::get(LHS0->
getType(), *LHSC));
1467 auto *FCmp = dyn_cast<FCmpInst>(
Op);
1468 if (!FCmp || !FCmp->hasOneUse())
1471 std::tie(ClassVal, ClassMask) =
1472 fcmpToClassTest(FCmp->getPredicate(), *FCmp->getParent()->getParent(),
1473 FCmp->getOperand(0), FCmp->getOperand(1));
1474 return ClassVal !=
nullptr;
1485 Value *ClassVal0 =
nullptr;
1486 Value *ClassVal1 =
nullptr;
1503 ClassVal0 == ClassVal1) {
1504 unsigned NewClassMask;
1506 case Instruction::And:
1507 NewClassMask = ClassMask0 & ClassMask1;
1509 case Instruction::Or:
1510 NewClassMask = ClassMask0 | ClassMask1;
1512 case Instruction::Xor:
1513 NewClassMask = ClassMask0 ^ ClassMask1;
1520 auto *II = cast<IntrinsicInst>(Op0);
1522 1, ConstantInt::get(II->getArgOperand(1)->getType(), NewClassMask));
1527 auto *II = cast<IntrinsicInst>(Op1);
1529 1, ConstantInt::get(II->getArgOperand(1)->getType(), NewClassMask));
1549Instruction *InstCombinerImpl::canonicalizeConditionalNegationViaMathToSelect(
1551 assert(
I.getOpcode() == BinaryOperator::Xor &&
"Only for xor!");
1556 !
Cond->getType()->isIntOrIntVectorTy(1) ||
1570 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1571 "Expecting and/or op for fcmp transform");
1591 Pred != NanPred ||
X->getType() !=
Y->getType())
1595 Pred != NanPred ||
X->getType() !=
Y->getType())
1601 if (
auto *NewFCmpInst = dyn_cast<FCmpInst>(NewFCmp)) {
1603 NewFCmpInst->copyIRFlags(Op0);
1604 NewFCmpInst->andIRFlags(BO10);
1615 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1616 "Trying to match De Morgan's Laws with something other than and/or");
1620 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1622 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1648bool InstCombinerImpl::shouldOptimizeCast(
CastInst *CI) {
1657 if (
const auto *PrecedingCI = dyn_cast<CastInst>(CastSrc))
1658 if (isEliminableCastPair(PrecedingCI, CI))
1684 return new ZExtInst(NewOp, DestTy);
1692 return new SExtInst(NewOp, DestTy);
1701 auto LogicOpc =
I.getOpcode();
1702 assert(
I.isBitwiseLogicOp() &&
"Unexpected opcode for bitwise logic folding");
1704 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1710 auto FoldBitwiseICmpZeroWithICmp = [&](
Value *Op0,
1726 auto *ICmpR = cast<ZExtInst>(Op1)->getOperand(0);
1732 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op0, Op1))
1735 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op1, Op0))
1738 CastInst *Cast0 = dyn_cast<CastInst>(Op0);
1744 Type *DestTy =
I.getType();
1752 CastInst *Cast1 = dyn_cast<CastInst>(Op1);
1769 unsigned XNumBits =
X->getType()->getScalarSizeInBits();
1770 unsigned YNumBits =
Y->getType()->getScalarSizeInBits();
1771 if (XNumBits < YNumBits)
1789 shouldOptimizeCast(Cast0) && shouldOptimizeCast(Cast1)) {
1800 assert(
I.getOpcode() == Instruction::And);
1801 Value *Op0 =
I.getOperand(0);
1802 Value *Op1 =
I.getOperand(1);
1810 return BinaryOperator::CreateXor(
A,
B);
1826 assert(
I.getOpcode() == Instruction::Or);
1827 Value *Op0 =
I.getOperand(0);
1828 Value *Op1 =
I.getOperand(1);
1853 return BinaryOperator::CreateXor(
A,
B);
1873 Value *Op0 =
And.getOperand(0), *Op1 =
And.getOperand(1);
1887 if (!isa<VectorType>(Ty) && !shouldChangeType(Ty,
X->getType()))
1894 if (Opc == Instruction::LShr || Opc == Instruction::Shl)
1911 assert(Opcode == Instruction::And || Opcode == Instruction::Or);
1915 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1917 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1924 const auto matchNotOrAnd =
1925 [Opcode, FlippedOpcode](
Value *
Op,
auto m_A,
auto m_B,
auto m_C,
1926 Value *&
X,
bool CountUses =
false) ->
bool {
1927 if (CountUses && !
Op->hasOneUse())
1934 return !CountUses ||
X->hasOneUse();
1950 return (Opcode == Instruction::Or)
1960 return (Opcode == Instruction::Or)
1983 if (Opcode == Instruction::Or && Op0->
hasOneUse() &&
1990 Value *
Or = cast<BinaryOperator>(
X)->getOperand(0);
2022 return (Opcode == Instruction::Or)
2024 : BinaryOperator::CreateOr(
Xor,
X);
2058 if (!isa<Constant>(
X) && !isa<Constant>(
Y) && !isa<Constant>(Z)) {
2060 if (!
X->hasOneUse()) {
2065 if (!
Y->hasOneUse()) {
2086 Type *Ty =
I.getType();
2088 Value *Op0 =
I.getOperand(0);
2089 Value *Op1 =
I.getOperand(1);
2101 case Instruction::And:
2102 if (
C->countl_one() < LastOneMath)
2105 case Instruction::Xor:
2106 case Instruction::Or:
2107 if (
C->countl_zero() < LastOneMath)
2116 ConstantInt::get(Ty, *C2), Op0);
2123 assert((
I.isBitwiseLogicOp() ||
I.getOpcode() == Instruction::Add) &&
2124 "Unexpected opcode");
2127 Constant *ShiftedC1, *ShiftedC2, *AddC;
2128 Type *Ty =
I.getType();
2142 auto *Op0Inst = dyn_cast<Instruction>(
I.getOperand(0));
2143 auto *Op1Inst = dyn_cast<Instruction>(
I.getOperand(1));
2144 if (!Op0Inst || !Op1Inst)
2150 if (ShiftOp != Op1Inst->getOpcode())
2154 if (
I.getOpcode() == Instruction::Add && ShiftOp != Instruction::Shl)
2174 assert(
I.isBitwiseLogicOp() &&
"Should and/or/xor");
2175 if (!
I.getOperand(0)->hasOneUse())
2182 if (
Y && (!
Y->hasOneUse() ||
X->getIntrinsicID() !=
Y->getIntrinsicID()))
2188 if (!
Y && (!(IID == Intrinsic::bswap || IID == Intrinsic::bitreverse) ||
2193 case Intrinsic::fshl:
2194 case Intrinsic::fshr: {
2195 if (
X->getOperand(2) !=
Y->getOperand(2))
2198 Builder.
CreateBinOp(
I.getOpcode(),
X->getOperand(0),
Y->getOperand(0));
2200 Builder.
CreateBinOp(
I.getOpcode(),
X->getOperand(1),
Y->getOperand(1));
2204 case Intrinsic::bswap:
2205 case Intrinsic::bitreverse: {
2207 I.getOpcode(),
X->getOperand(0),
2208 Y ?
Y->getOperand(0)
2209 : ConstantInt::get(
I.getType(), IID == Intrinsic::bswap
2228 unsigned Depth = 0) {
2235 auto *
I = dyn_cast<BinaryOperator>(V);
2236 if (!
I || !
I->isBitwiseLogicOp() ||
Depth >= 3)
2239 if (!
I->hasOneUse())
2240 SimplifyOnly =
true;
2243 SimplifyOnly, IC,
Depth + 1);
2245 SimplifyOnly, IC,
Depth + 1);
2246 if (!NewOp0 && !NewOp1)
2250 NewOp0 =
I->getOperand(0);
2252 NewOp1 =
I->getOperand(1);
2267 Type *Ty =
I.getType();
2301 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2336 Constant *NewC = ConstantInt::get(Ty, *
C & *XorC);
2339 return BinaryOperator::CreateXor(
And, NewC);
2350 APInt Together = *
C & *OrC;
2353 return BinaryOperator::CreateOr(
And, ConstantInt::get(Ty, Together));
2357 const APInt *ShiftC;
2359 ShiftC->
ult(Width)) {
2364 Constant *ShAmtC = ConstantInt::get(Ty, ShiftC->
zext(Width));
2365 return BinaryOperator::CreateLShr(Sext, ShAmtC);
2373 return BinaryOperator::CreateLShr(
X, ConstantInt::get(Ty, *ShiftC));
2381 if (Op0->
hasOneUse() &&
C->isPowerOf2() && (*AddC & (*
C - 1)) == 0) {
2382 assert((*
C & *AddC) != 0 &&
"Expected common bit");
2384 return BinaryOperator::CreateXor(NewAnd, Op1);
2391 switch (
B->getOpcode()) {
2392 case Instruction::Xor:
2393 case Instruction::Or:
2394 case Instruction::Mul:
2395 case Instruction::Add:
2396 case Instruction::Sub:
2412 C->isIntN(
X->getType()->getScalarSizeInBits())) {
2413 unsigned XWidth =
X->getType()->getScalarSizeInBits();
2414 Constant *TruncC1 = ConstantInt::get(
X->getType(), C1->
trunc(XWidth));
2418 Constant *TruncC = ConstantInt::get(
X->getType(),
C->trunc(XWidth));
2428 C->isMask(
X->getType()->getScalarSizeInBits())) {
2438 C->isMask(
X->getType()->getScalarSizeInBits())) {
2472 if (
C->isPowerOf2() &&
2475 int Log2C =
C->exactLogBase2();
2477 cast<BinaryOperator>(Op0)->getOpcode() == Instruction::Shl;
2478 int BitNum = IsShiftLeft ? Log2C - Log2ShiftC : Log2ShiftC - Log2C;
2479 assert(BitNum >= 0 &&
"Expected demanded bits to handle impossible mask");
2512 if (Cmp->isZeroValue()) {
2537 Attribute::NoImplicitFloat)) {
2551 X->getType()->getScalarSizeInBits())))) {
2553 auto *SanitizedSignMask = cast<Constant>(Op1);
2561 return BinaryOperator::CreateAnd(SExt, SanitizedSignMask);
2567 if (
I.getType()->isIntOrIntVectorTy(1)) {
2568 if (
auto *SI0 = dyn_cast<SelectInst>(Op0)) {
2570 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
true))
2573 if (
auto *SI1 = dyn_cast<SelectInst>(Op1)) {
2575 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
true))
2590 return BinaryOperator::CreateAnd(Op0,
B);
2593 return BinaryOperator::CreateAnd(Op1,
B);
2601 if (NotC !=
nullptr)
2602 return BinaryOperator::CreateAnd(Op0, NotC);
2611 if (NotC !=
nullptr)
2621 return BinaryOperator::CreateAnd(
A,
B);
2629 return BinaryOperator::CreateAnd(
A,
B);
2658 bool IsLogical = isa<SelectInst>(Op1);
2660 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
2662 foldAndOrOfICmps(
LHS, Cmp,
I,
true, IsLogical))
2667 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
2668 if (
Value *Res = foldAndOrOfICmps(
LHS, Cmp,
I,
true,
2675 bool IsLogical = isa<SelectInst>(Op0);
2677 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
2679 foldAndOrOfICmps(Cmp,
RHS,
I,
true, IsLogical))
2684 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
2685 if (
Value *Res = foldAndOrOfICmps(Cmp,
RHS,
I,
true,
2693 if (
FCmpInst *
LHS = dyn_cast<FCmpInst>(
I.getOperand(0)))
2694 if (
FCmpInst *
RHS = dyn_cast<FCmpInst>(
I.getOperand(1)))
2695 if (
Value *Res = foldLogicOfFCmps(
LHS,
RHS,
true))
2701 if (
Instruction *CastedAnd = foldCastedBitwiseLogic(
I))
2714 A->getType()->isIntOrIntVectorTy(1))
2720 A->getType()->isIntOrIntVectorTy(1))
2725 A->getType()->isIntOrIntVectorTy(1))
2732 if (
A->getType()->isIntOrIntVectorTy(1))
2745 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2754 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2765 Value *Start =
nullptr, *Step =
nullptr;
2773 return Canonicalized;
2775 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
2787 return BinaryOperator::CreateAnd(V, Op1);
2791 return BinaryOperator::CreateAnd(Op0, V);
2798 bool MatchBitReversals) {
2806 for (
auto *Inst : Insts)
2811std::optional<std::pair<Intrinsic::ID, SmallVector<Value *, 3>>>
2815 assert(
Or.getOpcode() == BinaryOperator::Or &&
"Expecting or instruction");
2817 unsigned Width =
Or.getType()->getScalarSizeInBits();
2822 return std::nullopt;
2829 if (isa<BinaryOperator>(Or0) && isa<BinaryOperator>(Or1)) {
2830 Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
2836 return std::nullopt;
2839 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2845 Or1->
getOpcode() == BinaryOperator::LShr &&
2846 "Illegal or(shift,shift) pair");
2850 auto matchShiftAmount = [&](
Value *L,
Value *R,
unsigned Width) ->
Value * {
2854 if (
LI->ult(Width) && RI->
ult(Width) && (*
LI + *RI) == Width)
2855 return ConstantInt::get(L->getType(), *
LI);
2879 if (ShVal0 != ShVal1)
2890 unsigned Mask = Width - 1;
2914 Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, Width);
2916 ShAmt = matchShiftAmount(ShAmt1, ShAmt0, Width);
2920 return std::nullopt;
2922 FShiftArgs = {ShVal0, ShVal1, ShAmt};
2923 }
else if (isa<ZExtInst>(Or0) || isa<ZExtInst>(Or1)) {
2935 if (!isa<ZExtInst>(Or1))
2939 const APInt *ZextHighShlAmt;
2942 return std::nullopt;
2946 return std::nullopt;
2948 unsigned HighSize =
High->getType()->getScalarSizeInBits();
2949 unsigned LowSize =
Low->getType()->getScalarSizeInBits();
2952 if (ZextHighShlAmt->
ult(LowSize) || ZextHighShlAmt->
ugt(Width - HighSize))
2953 return std::nullopt;
2960 if (!isa<ZExtInst>(
Y))
2963 const APInt *ZextLowShlAmt;
2970 if (*ZextLowShlAmt + *ZextHighShlAmt != Width)
2976 ZextLowShlAmt->
ule(Width - LowSize) &&
"Invalid concat");
2978 FShiftArgs = {U, U, ConstantInt::get(Or0->
getType(), *ZextHighShlAmt)};
2983 if (FShiftArgs.
empty())
2984 return std::nullopt;
2986 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
2987 return std::make_pair(IID, FShiftArgs);
2993 auto [IID, FShiftArgs] = *Opt;
3004 assert(
Or.getOpcode() == Instruction::Or &&
"bswap requires an 'or'");
3005 Value *Op0 =
Or.getOperand(0), *Op1 =
Or.getOperand(1);
3009 if ((Width & 1) != 0)
3011 unsigned HalfWidth = Width / 2;
3014 if (!isa<ZExtInst>(Op0))
3018 Value *LowerSrc, *ShlVal, *UpperSrc;
3031 NewUpper = Builder.
CreateShl(NewUpper, HalfWidth);
3039 Value *LowerBSwap, *UpperBSwap;
3042 return ConcatIntrinsicCalls(Intrinsic::bswap, UpperBSwap, LowerBSwap);
3046 Value *LowerBRev, *UpperBRev;
3049 return ConcatIntrinsicCalls(Intrinsic::bitreverse, UpperBRev, LowerBRev);
3056 unsigned NumElts = cast<FixedVectorType>(C1->
getType())->getNumElements();
3057 for (
unsigned i = 0; i != NumElts; ++i) {
3060 if (!EltC1 || !EltC2)
3079 Type *Ty =
A->getType();
3095 if (
A->getType()->isIntOrIntVectorTy()) {
3097 if (NumSignBits ==
A->getType()->getScalarSizeInBits() &&
3120 Cond->getType()->isIntOrIntVectorTy(1)) {
3146 Cond->getType()->isIntOrIntVectorTy(1) &&
3160 Value *
D,
bool InvertFalseVal) {
3163 Type *OrigType =
A->getType();
3166 if (
Value *
Cond = getSelectCondition(
A,
B, InvertFalseVal)) {
3171 Type *SelTy =
A->getType();
3172 if (
auto *VecTy = dyn_cast<VectorType>(
Cond->getType())) {
3174 unsigned Elts = VecTy->getElementCount().getKnownMinValue();
3195 bool IsAnd,
bool IsLogical,
3202 IsAnd ?
LHS->getInversePredicate() :
LHS->getPredicate();
3204 IsAnd ?
RHS->getInversePredicate() :
RHS->getPredicate();
3213 auto MatchRHSOp = [LHS0, CInt](
const Value *RHSOp) {
3216 (CInt->
isZero() && RHSOp == LHS0);
3247 if (
Value *V = foldAndOrOfICmpsOfAndWithPow2(LHS, RHS, &
I, IsAnd, IsLogical))
3251 Value *LHS0 =
LHS->getOperand(0), *RHS0 =
RHS->getOperand(0);
3252 Value *LHS1 =
LHS->getOperand(1), *RHS1 =
RHS->getOperand(1);
3253 const APInt *LHSC =
nullptr, *RHSC =
nullptr;
3260 if (LHS0 == RHS1 && LHS1 == RHS0) {
3264 if (LHS0 == RHS0 && LHS1 == RHS1) {
3267 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
3316 if (IsAnd && !IsLogical)
3334 if (
Value *
X = foldEqOfParts(LHS, RHS, IsAnd))
3369 const APInt *AndC, *SmallC =
nullptr, *BigC =
nullptr;
3383 if (SmallC && BigC) {
3384 unsigned BigBitSize = BigC->getBitWidth();
3403 bool TrueIfSignedL, TrueIfSignedR;
3409 if ((TrueIfSignedL && !TrueIfSignedR &&
3412 (!TrueIfSignedL && TrueIfSignedR &&
3419 if ((TrueIfSignedL && !TrueIfSignedR &&
3422 (!TrueIfSignedL && TrueIfSignedR &&
3431 return foldAndOrOfICmpsUsingRanges(LHS, RHS, IsAnd);
3467 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
3468 Type *Ty =
I.getType();
3470 if (
auto *SI0 = dyn_cast<SelectInst>(Op0)) {
3472 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
false))
3475 if (
auto *SI1 = dyn_cast<SelectInst>(Op1)) {
3477 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
false))
3508 return BinaryOperator::CreateXor(
Or, ConstantInt::get(Ty, *CV));
3516 return BinaryOperator::CreateMul(
X, IncrementY);
3525 const APInt *C0, *C1;
3544 if ((*C0 & *C1).
isZero()) {
3549 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
3550 return BinaryOperator::CreateAnd(
A, C01);
3556 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
3557 return BinaryOperator::CreateAnd(
B, C01);
3561 const APInt *C2, *C3;
3566 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
3567 return BinaryOperator::CreateAnd(
Or, C01);
3577 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D))
3579 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B))
3581 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D))
3583 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B))
3585 if (
Value *V = matchSelectFromAndOr(
B,
D,
A,
C))
3587 if (
Value *V = matchSelectFromAndOr(
B,
D,
C,
A))
3589 if (
Value *V = matchSelectFromAndOr(
D,
B,
A,
C))
3591 if (
Value *V = matchSelectFromAndOr(
D,
B,
C,
A))
3600 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D,
true))
3602 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B,
true))
3604 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D,
true))
3606 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B,
true))
3613 return BinaryOperator::CreateOr(Op0,
C);
3618 return BinaryOperator::CreateOr(Op1,
C);
3624 bool SwappedForXor =
false;
3627 SwappedForXor =
true;
3634 return BinaryOperator::CreateOr(Op0,
B);
3636 return BinaryOperator::CreateOr(Op0,
A);
3642 return BinaryOperator::CreateOr(
A,
B);
3670 return BinaryOperator::CreateOr(Nand,
C);
3688 bool IsLogical = isa<SelectInst>(Op1);
3690 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
3692 foldAndOrOfICmps(
LHS, Cmp,
I,
false, IsLogical))
3697 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
3698 if (
Value *Res = foldAndOrOfICmps(
LHS, Cmp,
I,
false,
3705 bool IsLogical = isa<SelectInst>(Op0);
3707 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
3709 foldAndOrOfICmps(Cmp,
RHS,
I,
false, IsLogical))
3714 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
3715 if (
Value *Res = foldAndOrOfICmps(Cmp,
RHS,
I,
false,
3723 if (
FCmpInst *
LHS = dyn_cast<FCmpInst>(
I.getOperand(0)))
3724 if (
FCmpInst *
RHS = dyn_cast<FCmpInst>(
I.getOperand(1)))
3725 if (
Value *Res = foldLogicOfFCmps(
LHS,
RHS,
false))
3743 A->getType()->isIntOrIntVectorTy(1))
3756 return BinaryOperator::CreateOr(Inner, CI);
3763 Value *
X =
nullptr, *
Y =
nullptr;
3795 return BinaryOperator::CreateXor(
A,
B);
3811 Value *
Mul, *Ov, *MulIsNotZero, *UMulWithOv;
3828 if (
match(UMulWithOv, m_Intrinsic<Intrinsic::umul_with_overflow>(
3832 return BinaryOperator::CreateAnd(NotNullA, NotNullB);
3841 const APInt *C1, *C2;
3857 : C2->
uadd_ov(*C1, Overflow));
3861 return BinaryOperator::CreateOr(Ov, NewCmp);
3881 Value *Start =
nullptr, *Step =
nullptr;
3899 return BinaryOperator::CreateOr(
3911 return BinaryOperator::CreateOr(
3919 return Canonicalized;
3921 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
3942 Attribute::NoImplicitFloat)) {
3955 if ((KnownX.
One & *C2) == *C2)
3956 return BinaryOperator::CreateAnd(
X, ConstantInt::get(Ty, *C1 | *C2));
3965 return BinaryOperator::CreateOr(V, Op1);
3969 return BinaryOperator::CreateOr(Op0, V);
3978 assert(
I.getOpcode() == Instruction::Xor);
3979 Value *Op0 =
I.getOperand(0);
3980 Value *Op1 =
I.getOperand(1);
3991 return BinaryOperator::CreateXor(
A,
B);
3999 return BinaryOperator::CreateXor(
A,
B);
4007 return BinaryOperator::CreateXor(
A,
B);
4029 assert(
I.getOpcode() == Instruction::Xor &&
I.getOperand(0) == LHS &&
4030 I.getOperand(1) == RHS &&
"Should be 'xor' with these operands");
4033 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
4034 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
4037 if (LHS0 == RHS1 && LHS1 == RHS0) {
4041 if (LHS0 == RHS0 && LHS1 == RHS1) {
4044 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
4052 const APInt *LC, *RC;
4061 bool TrueIfSignedL, TrueIfSignedR;
4077 if (CRUnion && CRIntersect)
4078 if (
auto CR = CRUnion->exactIntersectWith(CRIntersect->inverse())) {
4079 if (CR->isFullSet())
4081 if (CR->isEmptySet())
4086 CR->getEquivalentICmp(NewPred, NewC,
Offset);
4095 ConstantInt::get(Ty, NewC));
4113 if (OrICmp == LHS && AndICmp == RHS) {
4118 if (OrICmp == RHS && AndICmp == LHS) {
4125 Y->setPredicate(
Y->getInversePredicate());
4127 if (!
Y->hasOneUse()) {
4138 Y->replaceUsesWithIf(NotY,
4139 [NotY](
Use &U) {
return U.getUser() != NotY; });
4179 return BinaryOperator::CreateXor(NewA,
X);
4185 Type *EltTy =
C->getType()->getScalarType();
4191 return BinaryOperator::CreateOr(
LHS,
RHS);
4206 return A ==
C ||
A ==
D ||
B ==
C ||
B ==
D;
4215 return BinaryOperator::CreateOr(
X, NotY);
4223 return BinaryOperator::CreateOr(
Y, NotX);
4233 assert(
Xor.getOpcode() == Instruction::Xor &&
"Expected an xor instruction.");
4239 Value *Op0 =
Xor.getOperand(0), *Op1 =
Xor.getOperand(1);
4254 auto *
Add = cast<BinaryOperator>(Op0);
4256 Add->hasNoSignedWrap());
4264 auto *
I = dyn_cast<Instruction>(
Op);
4271 auto *
I = cast<Instruction>(
Op);
4274 Op->replaceUsesWithIf(NotOp,
4275 [NotOp](
Use &U) {
return U.getUser() != NotOp; });
4297 bool IsBinaryOp = isa<BinaryOperator>(
I);
4337 bool IsBinaryOp = isa<BinaryOperator>(
I);
4339 Value *NotOp0 =
nullptr;
4340 Value *NotOp1 =
nullptr;
4341 Value **OpToInvert =
nullptr;
4386 Type *Ty =
I.getType();
4390 return BinaryOperator::CreateOr(
X, NotY);
4401 return BinaryOperator::CreateAnd(
X, NotY);
4416 return BinaryOperator::CreateAnd(DecX, NotY);
4421 return BinaryOperator::CreateAShr(
X,
Y);
4427 return BinaryOperator::CreateAShr(
X,
Y);
4493 Type *SextTy = cast<BitCastOperator>(NotOp)->getSrcTy();
4499 if (
auto *NotOpI = dyn_cast<Instruction>(NotOp))
4506 auto *II = dyn_cast<IntrinsicInst>(NotOp);
4507 if (II && II->hasOneUse()) {
4515 if (II->getIntrinsicID() == Intrinsic::is_fpclass) {
4516 ConstantInt *ClassMask = cast<ConstantInt>(II->getArgOperand(1));
4518 1, ConstantInt::get(ClassMask->
getType(),
4533 if (
auto *Sel = dyn_cast<SelectInst>(NotOp)) {
4534 Value *TV = Sel->getTrueValue();
4535 Value *FV = Sel->getFalseValue();
4536 auto *CmpT = dyn_cast<CmpInst>(TV);
4537 auto *CmpF = dyn_cast<CmpInst>(FV);
4538 bool InvertibleT = (CmpT && CmpT->hasOneUse()) || isa<Constant>(TV);
4539 bool InvertibleF = (CmpF && CmpF->hasOneUse()) || isa<Constant>(FV);
4540 if (InvertibleT && InvertibleF) {
4542 CmpT->setPredicate(CmpT->getInversePredicate());
4546 CmpF->setPredicate(CmpF->getInversePredicate());
4604 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
4608 return BinaryOperator::CreateDisjointOr(Op0, Op1);
4625 return BinaryOperator::CreateXor(
4648 *CA ==
X->getType()->getScalarSizeInBits() - 1 &&
4656 Type *Ty =
I.getType();
4664 return BinaryOperator::CreateSub(ConstantInt::get(Ty, *
C + *RHSC),
X);
4668 return BinaryOperator::CreateAdd(
X, ConstantInt::get(Ty, *
C + *RHSC));
4673 return BinaryOperator::CreateXor(
X, ConstantInt::get(Ty, *
C ^ *RHSC));
4678 auto *II = dyn_cast<IntrinsicInst>(Op0);
4681 if ((IID == Intrinsic::ctlz || IID == Intrinsic::cttz) &&
4684 IID = (IID == Intrinsic::ctlz) ? Intrinsic::cttz : Intrinsic::ctlz;
4696 return BinaryOperator::CreateShl(NotX, ConstantInt::get(Ty, *
C));
4702 return BinaryOperator::CreateLShr(NotX, ConstantInt::get(Ty, *
C));
4721 Attribute::NoImplicitFloat)) {
4745 return BinaryOperator::CreateXor(Opnd0, ConstantInt::get(Ty, FoldConst));
4778 return BinaryOperator::CreateXor(
4784 return BinaryOperator::CreateXor(
4790 return BinaryOperator::CreateOr(
A,
B);
4794 return BinaryOperator::CreateOr(
A,
B);
4804 return BinaryOperator::CreateOr(
A,
B);
4819 if (
B ==
C ||
B ==
D)
4830 if (
I.getType()->isIntOrIntVectorTy(1) &&
4833 bool NeedFreeze = isa<SelectInst>(Op0) && isa<SelectInst>(Op1) &&
B ==
D;
4834 if (
B ==
C ||
B ==
D)
4846 if (
auto *
LHS = dyn_cast<ICmpInst>(
I.getOperand(0)))
4847 if (
auto *
RHS = dyn_cast<ICmpInst>(
I.getOperand(1)))
4851 if (
Instruction *CastedXor = foldCastedBitwiseLogic(
I))
4871 return Canonicalized;
4873 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
4876 if (
Instruction *Folded = canonicalizeConditionalNegationViaMathToSelect(
I))
amdgpu AMDGPU Register Bank Select
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static bool isSigned(unsigned int Opcode)
static unsigned conjugateICmpMask(unsigned Mask)
Convert an analysis of a masked ICmp into its equivalent if all boolean operations had the opposite s...
static Instruction * foldNotXor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static bool matchIsFPClassLikeFCmp(Value *Op, Value *&ClassVal, uint64_t &ClassMask)
Match an fcmp against a special value that performs a test possible by llvm.is.fpclass.
static Value * foldSignedTruncationCheck(ICmpInst *ICmp0, ICmpInst *ICmp1, Instruction &CxtI, InstCombiner::BuilderTy &Builder)
General pattern: X & Y.
static Instruction * visitMaskedMerge(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
If we have a masked merge, in the canonical form of: (assuming that A only has one use....
static Instruction * canonicalizeAbs(BinaryOperator &Xor, InstCombiner::BuilderTy &Builder)
Canonicalize a shifty way to code absolute value to the more common pattern that uses negation and se...
static Value * foldUnsignedUnderflowCheck(ICmpInst *ZeroICmp, ICmpInst *UnsignedICmp, bool IsAnd, const SimplifyQuery &Q, InstCombiner::BuilderTy &Builder)
Commuted variants are assumed to be handled by calling this function again with the parameters swappe...
static Instruction * foldOrToXor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static Value * simplifyAndOrWithOpReplaced(Value *V, Value *Op, Value *RepOp, bool SimplifyOnly, InstCombinerImpl &IC, unsigned Depth=0)
static Instruction * matchDeMorgansLaws(BinaryOperator &I, InstCombiner &IC)
Match variations of De Morgan's Laws: (~A & ~B) == (~(A | B)) (~A | ~B) == (~(A & B))
static Value * foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, Value *A, Value *B, Value *C, Value *D, Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR, InstCombiner::BuilderTy &Builder)
Try to fold (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E) into a single (icmp(A & X) ==/!...
static Value * foldIsPowerOf2OrZero(ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd, InstCombiner::BuilderTy &Builder)
Fold (icmp eq ctpop(X) 1) | (icmp eq X 0) into (icmp ult ctpop(X) 2) and fold (icmp ne ctpop(X) 1) & ...
static Instruction * foldAndToXor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static unsigned getMaskedICmpType(Value *A, Value *B, Value *C, ICmpInst::Predicate Pred)
Return the set of patterns (from MaskedICmpType) that (icmp SCC (A & B), C) satisfies.
static Instruction * foldXorToXor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
A ^ B can be specified using other logic ops in a variety of patterns.
static bool canNarrowShiftAmt(Constant *C, unsigned BitWidth)
Return true if a constant shift amount is always less than the specified bit-width.
static Instruction * foldLogicCastConstant(BinaryOperator &Logic, CastInst *Cast, InstCombinerImpl &IC)
Fold {and,or,xor} (cast X), C.
static Value * foldAndOrOfICmpEqConstantAndICmp(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, bool IsLogical, IRBuilderBase &Builder)
static bool canFreelyInvert(InstCombiner &IC, Value *Op, Instruction *IgnoredUser)
static Value * foldNegativePower2AndShiftedMask(Value *A, Value *B, Value *D, Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR, InstCombiner::BuilderTy &Builder)
Try to fold (icmp(A & B) == 0) & (icmp(A & D) != E) into (icmp A u< D) iff B is a contiguous set of o...
static Value * matchIsFiniteTest(InstCombiner::BuilderTy &Builder, FCmpInst *LHS, FCmpInst *RHS)
and (fcmp ord x, 0), (fcmp u* x, inf) -> fcmp o* x, inf
static Value * foldPowerOf2AndShiftedMask(ICmpInst *Cmp0, ICmpInst *Cmp1, bool JoinedByAnd, InstCombiner::BuilderTy &Builder)
Try to fold ((icmp X u< P) & (icmp(X & M) != M)) or ((icmp X s> -1) & (icmp(X & M) !...
static Value * stripSignOnlyFPOps(Value *Val)
Ignore all operations which only change the sign of a value, returning the underlying magnitude value...
static Value * freelyInvert(InstCombinerImpl &IC, Value *Op, Instruction *IgnoredUser)
static Value * foldLogOpOfMaskedICmps(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, bool IsLogical, InstCombiner::BuilderTy &Builder)
Try to fold (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E) into a single (icmp(A & X) ==/!...
static Value * foldIsPowerOf2(ICmpInst *Cmp0, ICmpInst *Cmp1, bool JoinedByAnd, InstCombiner::BuilderTy &Builder)
Reduce a pair of compares that check if a value has exactly 1 bit set.
static Value * foldLogOpOfMaskedICmpsAsymmetric(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, Value *A, Value *B, Value *C, Value *D, Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR, unsigned LHSMask, unsigned RHSMask, InstCombiner::BuilderTy &Builder)
Try to fold (icmp(A & B) ==/!= 0) &/| (icmp(A & D) ==/!= E) into a single (icmp(A & X) ==/!...
static std::optional< IntPart > matchIntPart(Value *V)
Match an extraction of bits from an integer.
static Instruction * canonicalizeLogicFirst(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static Instruction * reassociateFCmps(BinaryOperator &BO, InstCombiner::BuilderTy &Builder)
This a limited reassociation for a special case (see above) where we are checking if two values are e...
static Value * getNewICmpValue(unsigned Code, bool Sign, Value *LHS, Value *RHS, InstCombiner::BuilderTy &Builder)
This is the complement of getICmpCode, which turns an opcode and two operands into either a constant ...
static std::optional< std::pair< unsigned, unsigned > > getMaskedTypeForICmpPair(Value *&A, Value *&B, Value *&C, Value *&D, Value *&E, ICmpInst *LHS, ICmpInst *RHS, ICmpInst::Predicate &PredL, ICmpInst::Predicate &PredR)
Handle (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E).
static Value * extractIntPart(const IntPart &P, IRBuilderBase &Builder)
Materialize an extraction of bits from an integer in IR.
static bool matchUnorderedInfCompare(FCmpInst::Predicate P, Value *LHS, Value *RHS)
Matches fcmp u__ x, +/-inf.
static Instruction * matchOrConcat(Instruction &Or, InstCombiner::BuilderTy &Builder)
Attempt to combine or(zext(x),shl(zext(y),bw/2) concat packing patterns.
static bool matchIsNotNaN(FCmpInst::Predicate P, Value *LHS, Value *RHS)
Matches canonical form of isnan, fcmp ord x, 0.
static bool areInverseVectorBitmasks(Constant *C1, Constant *C2)
If all elements of two constant vectors are 0/-1 and inverses, return true.
MaskedICmpType
Classify (icmp eq (A & B), C) and (icmp ne (A & B), C) as matching patterns that can be simplified.
static Instruction * foldComplexAndOrPatterns(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
Try folding relatively complex patterns for both And and Or operations with all And and Or swapped.
static Value * getFCmpValue(unsigned Code, Value *LHS, Value *RHS, InstCombiner::BuilderTy &Builder)
This is the complement of getFCmpCode, which turns an opcode and two operands into either a FCmp inst...
static Instruction * matchFunnelShift(Instruction &Or, InstCombinerImpl &IC)
Match UB-safe variants of the funnel shift intrinsic.
static Instruction * reassociateForUses(BinaryOperator &BO, InstCombinerImpl::BuilderTy &Builder)
Try to reassociate a pair of binops so that values with one use only are part of the same instruction...
static Instruction * foldBitwiseLogicWithIntrinsics(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static Value * foldAndOrOfICmpsWithConstEq(ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd, bool IsLogical, InstCombiner::BuilderTy &Builder, const SimplifyQuery &Q)
Reduce logic-of-compares with equality to a constant by substituting a common operand with the consta...
This file provides internal interfaces used to implement the InstCombine.
This file provides the interface for the instcombine pass implementation.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static constexpr int Concat[]
support::ulittle16_t & Lo
support::ulittle16_t & Hi
bool bitwiseIsEqual(const APFloat &RHS) const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
APInt trunc(unsigned width) const
Truncate to new width.
unsigned countLeadingOnes() const
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
APInt usub_ov(const APInt &RHS, bool &Overflow) const
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isSignMask() const
Check if the APInt's value is returned by getSignMask.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
APInt sadd_ov(const APInt &RHS, bool &Overflow) const
bool intersects(const APInt &RHS) const
This operation tests if there are any pairs of corresponding bits between this APInt and RHS that are...
int32_t exactLogBase2() const
APInt reverseBits() const
APInt uadd_ov(const APInt &RHS, bool &Overflow) const
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countLeadingZeros() const
bool ule(const APInt &RHS) const
Unsigned less or equal comparison.
APInt shl(unsigned shiftAmt) const
Left-shift function.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
APInt ssub_ov(const APInt &RHS, bool &Overflow) const
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
const Function * getParent() const
Return the enclosing method, or null if none.
bool isSigned() const
Whether the intrinsic is signed or unsigned.
Instruction::BinaryOps getBinaryOp() const
Returns the binary operation underlying the intrinsic.
static BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name, BasicBlock::iterator InsertBefore)
Construct a binary instruction, given the opcode and the two operands.
BinaryOps getOpcode() const
static BinaryOperator * CreateNot(Value *Op, const Twine &Name, BasicBlock::iterator InsertBefore)
static BinaryOperator * CreateWithCopiedFlags(BinaryOps Opc, Value *V1, Value *V2, Value *CopyO, const Twine &Name, BasicBlock::iterator InsertBefore)
This class represents a no-op cast from one type to another.
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr, BasicBlock::iterator InsertBefore)
This is the base class for all instructions that perform data casts.
Type * getSrcTy() const
Return the source type, as a convenience.
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
static CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name, BasicBlock::iterator InsertBefore)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
static CastInst * CreateBitOrPointerCast(Value *S, Type *Ty, const Twine &Name, BasicBlock::iterator InsertBefore)
Create a BitCast, a PtrToInt, or an IntToPTr cast instruction.
Type * getDestTy() const
Return the destination type, as a convenience.
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ ICMP_ULT
unsigned less than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ ICMP_SGE
signed greater or equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Predicate getOrderedPredicate() const
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Predicate getPredicate() const
Return the predicate for this instruction.
static bool isUnordered(Predicate predicate)
Determine if the predicate is an unordered operation.
static Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getNot(Constant *C)
static Constant * getXor(Constant *C1, Constant *C2)
static Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getExactLogBase2(Constant *C)
If C is a scalar/fixed width vector of known powers of 2, then this function returns a new scalar/fix...
static Constant * getCompare(unsigned short pred, Constant *C1, Constant *C2, bool OnlyIfReduced=false)
Return an ICmp or FCmp comparison operator constant expression.
This is the shared class of boolean and integer constants.
bool isMinusOne() const
This function will return true iff every bit in this constant is set to true.
static ConstantInt * getTrue(LLVMContext &Context)
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static ConstantInt * getFalse(LLVMContext &Context)
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
const APInt & getValue() const
Return the constant as an APInt value reference.
This class represents a range of values.
std::optional< ConstantRange > exactUnionWith(const ConstantRange &CR) const
Union the two ranges and return the result if it can be represented exactly, otherwise return std::nu...
ConstantRange subtract(const APInt &CI) const
Subtract the specified constant from the endpoints of this constant range.
const APInt & getLower() const
Return the lower value for this range.
bool isWrappedSet() const
Return true if this set wraps around the unsigned domain.
const APInt & getUpper() const
Return the upper value for this range.
static ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)
Produce the exact range such that all values in the returned range satisfy the given predicate with a...
std::optional< ConstantRange > exactIntersectWith(const ConstantRange &CR) const
Intersect the two ranges and return the result if it can be represented exactly, otherwise return std...
This is an important base class in LLVM.
static Constant * replaceUndefsWith(Constant *C, Constant *Replacement)
Try to replace undefined constant C or undefined elements in C with Replacement.
static Constant * mergeUndefsWith(Constant *C, Constant *Other)
Merges undefs of a Constant with another Constant, along with the undefs already present.
static Constant * getAllOnesValue(Type *Ty)
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
bool isZeroValue() const
Return true if the value is negative zero or null value.
This class represents an Operation in the Expression.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
This instruction compares its operands according to the predicate given to the constructor.
Convenience struct for specifying and reasoning about fast-math flags.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
This instruction compares its operands according to the predicate given to the constructor.
Predicate getSignedPredicate() const
For example, EQ->EQ, SLE->SLE, UGT->SGT, etc.
bool isEquality() const
Return true if this predicate is either EQ or NE.
Common base class shared among various IRBuilders.
CallInst * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with 1 operand which is mangled on its type.
Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
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="")
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateIsNeg(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg < 0.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateICmpUGT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateLogicalAnd(Value *Cond1, Value *Cond2, const Twine &Name="")
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="")
Value * CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateIsNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg == 0.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateLogicalOr(Value *Cond1, Value *Cond2, const Twine &Name="")
Value * CreateFNeg(Value *V, const Twine &Name="", MDNode *FPMathTag=nullptr)
Instruction * canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(BinaryOperator &I)
Instruction * foldBinOpIntoSelectOrPhi(BinaryOperator &I)
This is a convenience wrapper function for the above two functions.
Instruction * visitOr(BinaryOperator &I)
bool SimplifyAssociativeOrCommutative(BinaryOperator &I)
Performs a few simplifications for operators which are associative or commutative.
Value * foldUsingDistributiveLaws(BinaryOperator &I)
Tries to simplify binary operations which some other binary operation distributes over.
Instruction * foldBinOpShiftWithShift(BinaryOperator &I)
Value * insertRangeTest(Value *V, const APInt &Lo, const APInt &Hi, bool isSigned, bool Inside)
Emit a computation of: (V >= Lo && V < Hi) if Inside is true, otherwise (V < Lo || V >= Hi).
bool sinkNotIntoLogicalOp(Instruction &I)
std::optional< std::pair< Intrinsic::ID, SmallVector< Value *, 3 > > > convertOrOfShiftsToFunnelShift(Instruction &Or)
Constant * getLosslessUnsignedTrunc(Constant *C, Type *TruncTy)
Instruction * visitAnd(BinaryOperator &I)
bool sinkNotIntoOtherHandOfLogicalOp(Instruction &I)
Instruction * foldBinopWithPhiOperands(BinaryOperator &BO)
For a binary operator with 2 phi operands, try to hoist the binary operation before the phi.
Value * simplifyRangeCheck(ICmpInst *Cmp0, ICmpInst *Cmp1, bool Inverted)
Try to fold a signed range checked with lower bound 0 to an unsigned icmp.
Instruction * tryFoldInstWithCtpopWithNot(Instruction *I)
Constant * getLosslessSignedTrunc(Constant *C, Type *TruncTy)
Instruction * visitXor(BinaryOperator &I)
bool SimplifyDemandedInstructionBits(Instruction &Inst)
Tries to simplify operands to an integer instruction based on its demanded bits.
Instruction * foldVectorBinop(BinaryOperator &Inst)
Canonicalize the position of binops relative to shufflevector.
Instruction * matchBSwapOrBitReverse(Instruction &I, bool MatchBSwaps, bool MatchBitReversals)
Given an initial instruction, check to see if it is the root of a bswap/bitreverse idiom.
void freelyInvertAllUsersOf(Value *V, Value *IgnoredUser=nullptr)
Freely adapt every user of V as-if V was changed to !V.
The core instruction combiner logic.
bool isFreeToInvert(Value *V, bool WillInvertAllUses, bool &DoesConsume)
Return true if the specified value is free to invert (apply ~ to).
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, unsigned Depth=0, const Instruction *CxtI=nullptr)
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
InstructionWorklist & Worklist
A worklist of the instructions that need to be simplified.
unsigned ComputeNumSignBits(const Value *Op, unsigned Depth=0, const Instruction *CxtI=nullptr) const
static Value * peekThroughBitcast(Value *V, bool OneUseOnly=false)
Return the source operand of a potentially bitcasted value while optionally checking if it has one us...
bool canFreelyInvertAllUsersOf(Instruction *V, Value *IgnoredUser)
Given i1 V, can every user of V be freely adapted if V is changed to !V ? InstCombine's freelyInvertA...
void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth, const Instruction *CxtI) const
bool MaskedValueIsZero(const Value *V, const APInt &Mask, unsigned Depth=0, const Instruction *CxtI=nullptr) const
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
const SimplifyQuery & getSimplifyQuery() const
void pushUsersToWorkList(Instruction &I)
When an instruction is simplified, add all users of the instruction to the work lists because they mi...
void push(Instruction *I)
Push the instruction onto the worklist stack.
void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
A wrapper class for inspecting calls to intrinsic functions.
This class represents a sign extension of integer types.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr, BasicBlock::iterator InsertBefore, Instruction *MDFrom=nullptr)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isIEEE() const
Return whether the type is IEEE compatible, as defined by the eponymous method in APFloat.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
iterator_range< user_iterator > users()
bool hasNUsesOrMore(unsigned N) const
Return true if this value has N uses or more.
bool hasNUses(unsigned N) const
Return true if this Value has exactly N uses.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
static VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
Represents an op.with.overflow intrinsic.
This class represents zero extension of integer types.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const APInt & umin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be unsigned.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
cst_pred_ty< is_lowbit_mask > m_LowBitMask()
Match an integer or vector with only the low bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
specific_intval< false > m_SpecificInt(APInt V)
Match a specific integer value or vector with all elements equal to the value.
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.
apfloat_match m_APFloatAllowUndef(const APFloat *&Res)
Match APFloat while allowing undefs in splat vector constants.
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)
apint_match m_APIntAllowUndef(const APInt *&Res)
Match APInt while allowing undefs in splat vector constants.
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power-of-2.
auto m_LogicalOp()
Matches either L && R or L || R where L and R are arbitrary values.
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWSub(const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, ZExtInst >, OpTy > m_ZExtOrSelf(const OpTy &Op)
bool match(Val *V, const Pattern &P)
cst_pred_ty< is_shifted_mask > m_ShiftedMask()
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
constantexpr_match m_ConstantExpr()
Match a constant expression or a constant that contains a constant expression.
cst_pred_ty< is_nonnegative > m_NonNegative()
Match an integer or vector of non-negative values.
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
match_combine_or< CastInst_match< OpTy, SExtInst >, OpTy > m_SExtOrSelf(const OpTy &Op)
BinOpPred_match< LHS, RHS, is_logical_shift_op > m_LogicalShift(const LHS &L, const RHS &R)
Matches logical shift operations.
match_combine_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)
Combine two pattern matchers matching L && R.
CmpClass_match< LHS, RHS, FCmpInst, FCmpInst::Predicate > m_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R)
CastOperator_match< OpTy, Instruction::Trunc > m_Trunc(const OpTy &Op)
Matches Trunc.
bind_ty< WithOverflowInst > m_WithOverflowInst(WithOverflowInst *&I)
Match a with overflow intrinsic, capturing it if we match.
BinaryOp_match< LHS, RHS, Instruction::Xor, true > m_c_Xor(const LHS &L, const RHS &R)
Matches an Xor with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
cst_pred_ty< is_zero_int > m_ZeroInt()
Match an integer 0 or a vector with all elements equal to 0.
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate > m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)
OneUse_match< T > m_OneUse(const T &SubPattern)
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
BinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub > m_Neg(const ValTy &V)
Matches a 'Neg' as 'sub 0, V'.
match_combine_and< class_match< Constant >, match_unless< constantexpr_match > > m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
cst_pred_ty< is_negated_power2 > m_NegatedPower2()
Match a integer or vector negated power-of-2.
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate, true > m_c_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
DisjointOr_match< LHS, RHS, true > m_c_DisjointOr(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
match_combine_or< BinaryOp_match< LHS, RHS, Instruction::Add >, DisjointOr_match< LHS, RHS > > m_AddLike(const LHS &L, const RHS &R)
Match either "add" or "or disjoint".
CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
match_combine_or< match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty, true >, MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty, true > >, match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty, true >, MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty, true > > > m_c_MaxOrMin(const LHS &L, const RHS &R)
match_combine_or< CastOperator_match< OpTy, Instruction::Trunc >, OpTy > m_TruncOrSelf(const OpTy &Op)
match_combine_or< CastInst_match< OpTy, SExtInst >, NNegZExt_match< OpTy > > m_SExtLike(const OpTy &Op)
Match either "sext" or "zext nneg".
specific_intval< true > m_SpecificIntAllowUndef(APInt V)
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
cst_pred_ty< is_maxsignedvalue > m_MaxSignedValue()
Match an integer or vector with values having all bits except for the high bit set (0x7f....
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
AnyBinaryOp_match< LHS, RHS, true > m_c_BinOp(const LHS &L, const RHS &R)
Matches a BinaryOperator with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > > m_ZExtOrSExt(const OpTy &Op)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
BinOpPred_match< LHS, RHS, is_shift_op > m_Shift(const LHS &L, const RHS &R)
Matches shift operations.
cstfp_pred_ty< is_pos_zero_fp > m_PosZeroFP()
Match a floating-point positive zero.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
BinaryOp_match< cst_pred_ty< is_all_ones >, ValTy, Instruction::Xor, true > m_Not(const ValTy &V)
Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
m_Intrinsic_Ty< Opnd0 >::Ty m_BSwap(const Opnd0 &Op0)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
ElementWiseBitCast_match< OpTy > m_ElementWiseBitCast(const OpTy &Op)
m_Intrinsic_Ty< Opnd0 >::Ty m_FAbs(const Opnd0 &Op0)
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_CopySign(const Opnd0 &Op0, const Opnd1 &Op1)
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
match_unless< Ty > m_Unless(const Ty &M)
Match if the inner matcher does NOT match.
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
cst_pred_ty< icmp_pred_with_threshold > m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold)
Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.
NodeAddr< CodeNode * > Code
This is an optimization pass for GlobalISel generic memory operations.
Intrinsic::ID getInverseMinMaxIntrinsic(Intrinsic::ID MinMaxID)
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
Constant * getPredForFCmpCode(unsigned Code, Type *OpTy, CmpInst::Predicate &Pred)
This is the complement of getFCmpCode.
bool isKnownNonZero(const Value *V, const DataLayout &DL, 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 be non-zero when defined.
bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS, bool &TrueIfSigned)
Given an exploded icmp instruction, return true if the comparison only checks the sign bit.
bool predicatesFoldable(CmpInst::Predicate P1, CmpInst::Predicate P2)
Return true if both predicates match sign or if at least one of them is an equality comparison (which...
Value * simplifyOrInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an Or, fold the result or return null.
Value * simplifyXorInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an Xor, fold the result or return null.
bool matchSimpleRecurrence(const PHINode *P, BinaryOperator *&BO, Value *&Start, Value *&Step)
Attempt to match a simple first order recurrence cycle of the form: iv = phi Ty [Start,...
bool recognizeBSwapOrBitReverseIdiom(Instruction *I, bool MatchBSwaps, bool MatchBitReversals, SmallVectorImpl< Instruction * > &InsertedInsts)
Try to match a bswap or bitreverse idiom.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Value * simplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an And, fold the result or return null.
Value * simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an ICmpInst, fold the result or return null.
Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
bool isKnownNegative(const Value *V, const SimplifyQuery &DL, unsigned Depth=0)
Returns true if the given value is known be negative (i.e.
@ Or
Bitwise or logical OR of integers.
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
constexpr unsigned BitWidth
std::pair< Value *, FPClassTest > fcmpToClassTest(CmpInst::Predicate Pred, const Function &F, Value *LHS, Value *RHS, bool LookThroughSrc=true)
Returns a pair of values, which if passed to llvm.is.fpclass, returns the same result as an fcmp with...
APFloat neg(APFloat X)
Returns the negated value of the argument.
bool decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate &Pred, Value *&X, APInt &Mask, bool LookThroughTrunc=true)
Decompose an icmp into the form ((X & Mask) pred 0) if possible.
unsigned getICmpCode(CmpInst::Predicate Pred)
Encode a icmp predicate into a three bit mask.
unsigned getFCmpCode(CmpInst::Predicate CC)
Similar to getICmpCode but for FCmpInst.
Constant * getPredForICmpCode(unsigned Code, bool Sign, Type *OpTy, CmpInst::Predicate &Pred)
This is the complement of getICmpCode.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isNonNegative() const
Returns true if this value is known to be non-negative.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
SimplifyQuery getWithInstruction(const Instruction *I) const