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, *DCst, *OrigECst;
353 APInt ECst = *OrigECst;
359 if (*BCst == 0 || *DCst == 0)
370 Attribute::StrictFP)) {
371 Type *Ty = Src->getType()->getScalarType();
378 APInt FractionBits = ~ExpBits;
380 if (*BCst != FractionBits)
405 if ((((*BCst & *DCst) & ECst) == 0) &&
406 (*BCst & (*BCst ^ *DCst)).isPowerOf2()) {
407 APInt BorD = *BCst | *DCst;
408 APInt BandBxorDorE = (*BCst & (*BCst ^ *DCst)) | ECst;
409 Value *NewMask = ConstantInt::get(
A->getType(), BorD);
410 Value *NewMaskedValue = ConstantInt::get(
A->getType(), BandBxorDorE);
412 return Builder.
CreateICmp(NewCC, NewAnd, NewMaskedValue);
415 auto IsSubSetOrEqual = [](
const APInt *C1,
const APInt *C2) {
416 return (*C1 & *C2) == *C1;
418 auto IsSuperSetOrEqual = [](
const APInt *C1,
const APInt *C2) {
419 return (*C1 & *C2) == *C2;
428 if (!IsSubSetOrEqual(BCst, DCst) && !IsSuperSetOrEqual(BCst, DCst))
440 if (IsSubSetOrEqual(BCst, DCst))
441 return ConstantInt::get(
LHS->
getType(), !IsAnd);
451 if (IsSuperSetOrEqual(BCst, DCst))
456 assert(IsSubSetOrEqual(BCst, DCst) &&
"Precondition due to above code");
457 if ((*BCst & ECst) != 0)
463 return ConstantInt::get(
LHS->
getType(), !IsAnd);
475 "Expected equality predicates for masked type of icmps.");
487 LHS,
RHS, IsAnd,
A,
B,
D, E, PredL, PredR, Builder)) {
492 RHS,
LHS, IsAnd,
A,
D,
B,
C, PredR, PredL, Builder)) {
504 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *E =
nullptr;
506 std::optional<std::pair<unsigned, unsigned>> MaskPair =
511 "Expected equality predicates for masked type of icmps.");
512 unsigned LHSMask = MaskPair->first;
513 unsigned RHSMask = MaskPair->second;
514 unsigned Mask = LHSMask & RHSMask;
519 LHS,
RHS, IsAnd,
A,
B,
C,
D, E, PredL, PredR, LHSMask, RHSMask,
555 return Builder.
CreateICmp(NewCC, NewAnd, Zero);
564 return Builder.
CreateICmp(NewCC, NewAnd, NewOr);
579 const APInt *ConstB, *ConstD;
589 APInt NewMask = *ConstB & *ConstD;
590 if (NewMask == *ConstB)
592 else if (NewMask == *ConstD)
601 APInt NewMask = *ConstB | *ConstD;
602 if (NewMask == *ConstB)
604 else if (NewMask == *ConstD)
631 const APInt *OldConstC, *OldConstE;
637 const APInt ConstC = PredL !=
CC ? *ConstB ^ *OldConstC : *OldConstC;
638 const APInt ConstE = PredR !=
CC ? *ConstD ^ *OldConstE : *OldConstE;
640 if (((*ConstB & *ConstD) & (ConstC ^ ConstE)).getBoolValue())
641 return IsNot ? nullptr : ConstantInt::get(
LHS->
getType(), !IsAnd);
643 if (IsNot && !ConstB->
isSubsetOf(*ConstD) && !ConstD->isSubsetOf(*ConstB))
648 BD = *ConstB & *ConstD;
649 CE = ConstC & ConstE;
651 BD = *ConstB | *ConstD;
652 CE = ConstC | ConstE;
655 Value *CEVal = ConstantInt::get(
A->getType(), CE);
660 return FoldBMixed(NewCC,
false);
662 return FoldBMixed(NewCC,
true);
708 default:
return nullptr;
732 if (
LHS->getPredicate() != Pred ||
RHS->getPredicate() != Pred)
763Value *InstCombinerImpl::foldAndOrOfICmpsOfAndWithPow2(
ICmpInst *LHS,
769 if (
LHS->getPredicate() != Pred ||
RHS->getPredicate() != Pred)
779 if (L1 ==
R2 || L2 ==
R2)
837 auto tryToMatchSignedTruncationCheck = [](
ICmpInst *ICmp,
Value *&
X,
838 APInt &SignBitMask) ->
bool {
839 const APInt *I01, *I1;
843 I1->ugt(*I01) && I01->
shl(1) == *I1))
855 if (tryToMatchSignedTruncationCheck(ICmp1, X1, HighestBit))
857 else if (tryToMatchSignedTruncationCheck(ICmp0, X1, HighestBit))
862 assert(HighestBit.
isPowerOf2() &&
"expected to be power of two (non-zero)");
866 APInt &UnsetBitsMask) ->
bool {
870 Pred,
X, UnsetBitsMask,
878 UnsetBitsMask = *Mask;
887 if (!tryToDecompose(OtherICmp, X0, UnsetBitsMask))
890 assert(!UnsetBitsMask.
isZero() &&
"empty mask makes no sense.");
905 APInt SignBitsMask = ~(HighestBit - 1U);
912 if (!UnsetBitsMask.
isSubsetOf(SignBitsMask)) {
913 APInt OtherHighestBit = (~UnsetBitsMask) + 1U;
921 return Builder.
CreateICmpULT(
X, ConstantInt::get(
X->getType(), HighestBit),
922 CxtI.
getName() +
".simplified");
987 "Expected equality predicates for masked type of icmps.");
1007 const APInt *BCst, *DCst, *ECst;
1010 (isa<PoisonValue>(
B) ||
1015 if (
const auto *BVTy = dyn_cast<VectorType>(
B->getType())) {
1016 const auto *BFVTy = dyn_cast<FixedVectorType>(BVTy);
1017 const auto *BConst = dyn_cast<Constant>(
B);
1018 const auto *DConst = dyn_cast<Constant>(
D);
1019 const auto *EConst = dyn_cast<Constant>(E);
1021 if (!BFVTy || !BConst || !DConst || !EConst)
1024 for (
unsigned I = 0;
I != BFVTy->getNumElements(); ++
I) {
1025 const auto *BElt = BConst->getAggregateElement(
I);
1026 const auto *DElt = DConst->getAggregateElement(
I);
1027 const auto *EElt = EConst->getAggregateElement(
I);
1029 if (!BElt || !DElt || !EElt)
1031 if (!isReducible(BElt, DElt, EElt))
1036 if (!isReducible(
B,
D, E))
1054 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *E =
nullptr;
1060 std::optional<std::pair<unsigned, unsigned>> MaskPair =
1066 unsigned CmpMask0 = MaskPair->first;
1067 unsigned CmpMask1 = MaskPair->second;
1068 if ((CmpMask0 &
Mask_AllZeros) && (CmpMask1 == compareBMask)) {
1072 }
else if ((CmpMask0 == compareBMask) && (CmpMask1 &
Mask_AllZeros)) {
1083 ICmpInst *UnsignedICmp,
bool IsAnd,
1095 if (
match(UnsignedICmp,
1111 IsAnd && GetKnownNonZeroAndOther(
B,
A))
1114 !IsAnd && GetKnownNonZeroAndOther(
B,
A))
1131 return std::nullopt;
1133 unsigned NumOriginalBits =
X->getType()->getScalarSizeInBits();
1134 unsigned NumExtractedBits = V->getType()->getScalarSizeInBits();
1140 Shift->
ule(NumOriginalBits - NumExtractedBits))
1142 return {{
X, 0, NumExtractedBits}};
1150 Type *TruncTy = V->getType()->getWithNewBitWidth(
P.NumBits);
1151 if (TruncTy != V->getType())
1166 unsigned OpNo) -> std::optional<IntPart> {
1167 if (Pred ==
Cmp->getPredicate())
1176 return std::nullopt;
1185 return std::nullopt;
1187 return std::nullopt;
1192 return {{
I->getOperand(OpNo),
From,
C->getBitWidth() -
From}};
1195 std::optional<IntPart> L0 = GetMatchPart(Cmp0, 0);
1196 std::optional<IntPart> R0 = GetMatchPart(Cmp0, 1);
1197 std::optional<IntPart> L1 = GetMatchPart(Cmp1, 0);
1198 std::optional<IntPart> R1 = GetMatchPart(Cmp1, 1);
1199 if (!L0 || !R0 || !L1 || !R1)
1204 if (L0->From != L1->From || R0->From != R1->From) {
1205 if (L0->From != R1->From || R0->From != L1->From)
1212 if (L0->StartBit + L0->NumBits != L1->StartBit ||
1213 R0->StartBit + R0->NumBits != R1->StartBit) {
1214 if (L1->StartBit + L1->NumBits != L0->StartBit ||
1215 R1->StartBit + R1->NumBits != R0->StartBit)
1222 IntPart L = {L0->From, L0->StartBit, L0->NumBits + L1->NumBits};
1223 IntPart R = {R0->From, R0->StartBit, R0->NumBits + R1->NumBits};
1233 bool IsAnd,
bool IsLogical,
1262 if (!SubstituteCmp) {
1272 return Builder.
CreateBinOp(IsAnd ? Instruction::And : Instruction::Or, Cmp0,
1280Value *InstCombinerImpl::foldAndOrOfICmpsUsingRanges(
ICmpInst *ICmp1,
1285 const APInt *C1, *C2;
1292 const APInt *Offset1 =
nullptr, *Offset2 =
nullptr;
1327 if (!LowerDiff.
isPowerOf2() || LowerDiff != UpperDiff ||
1340 CR->getEquivalentICmp(NewPred, NewC,
Offset);
1372 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1373 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1382 FMF &=
RHS->getFastMathFlags();
1389 bool IsAnd,
bool IsLogicalSelect) {
1390 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1391 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1394 if (LHS0 == RHS1 && RHS0 == LHS1) {
1414 if (LHS0 == RHS0 && LHS1 == RHS1) {
1417 unsigned NewPred = IsAnd ? FCmpCodeL & FCmpCodeR : FCmpCodeL | FCmpCodeR;
1423 FMF &=
RHS->getFastMathFlags();
1430 if (!IsLogicalSelect &&
1461 auto [ClassValRHS, ClassMaskRHS] =
1464 auto [ClassValLHS, ClassMaskLHS] =
1466 if (ClassValLHS == ClassValRHS) {
1467 unsigned CombinedMask = IsAnd ? (ClassMaskLHS & ClassMaskRHS)
1468 : (ClassMaskLHS | ClassMaskRHS);
1470 Intrinsic::is_fpclass, {ClassValLHS->getType()},
1499 if (IsLessThanOrLessEqual(IsAnd ? PredR : PredL)) {
1503 if (IsLessThanOrLessEqual(IsAnd ? PredL : PredR)) {
1506 RHS->getFastMathFlags());
1510 ConstantFP::get(LHS0->
getType(), *LHSC));
1521 auto *FCmp = dyn_cast<FCmpInst>(
Op);
1522 if (!FCmp || !FCmp->hasOneUse())
1525 std::tie(ClassVal, ClassMask) =
1526 fcmpToClassTest(FCmp->getPredicate(), *FCmp->getParent()->getParent(),
1527 FCmp->getOperand(0), FCmp->getOperand(1));
1528 return ClassVal !=
nullptr;
1539 Value *ClassVal0 =
nullptr;
1540 Value *ClassVal1 =
nullptr;
1557 ClassVal0 == ClassVal1) {
1558 unsigned NewClassMask;
1560 case Instruction::And:
1561 NewClassMask = ClassMask0 & ClassMask1;
1563 case Instruction::Or:
1564 NewClassMask = ClassMask0 | ClassMask1;
1566 case Instruction::Xor:
1567 NewClassMask = ClassMask0 ^ ClassMask1;
1574 auto *
II = cast<IntrinsicInst>(Op0);
1576 1, ConstantInt::get(
II->getArgOperand(1)->getType(), NewClassMask));
1581 auto *
II = cast<IntrinsicInst>(Op1);
1583 1, ConstantInt::get(
II->getArgOperand(1)->getType(), NewClassMask));
1603Instruction *InstCombinerImpl::canonicalizeConditionalNegationViaMathToSelect(
1605 assert(
I.getOpcode() == BinaryOperator::Xor &&
"Only for xor!");
1610 !
Cond->getType()->isIntOrIntVectorTy(1) ||
1624 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1625 "Expecting and/or op for fcmp transform");
1644 X->getType() !=
Y->getType())
1648 X->getType() !=
Y->getType())
1654 if (
auto *NewFCmpInst = dyn_cast<FCmpInst>(NewFCmp)) {
1656 NewFCmpInst->copyIRFlags(Op0);
1657 NewFCmpInst->andIRFlags(BO10);
1668 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1669 "Trying to match De Morgan's Laws with something other than and/or");
1673 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1675 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1701bool InstCombinerImpl::shouldOptimizeCast(
CastInst *CI) {
1710 if (
const auto *PrecedingCI = dyn_cast<CastInst>(CastSrc))
1711 if (isEliminableCastPair(PrecedingCI, CI))
1737 return new ZExtInst(NewOp, DestTy);
1745 return new SExtInst(NewOp, DestTy);
1754 auto LogicOpc =
I.getOpcode();
1755 assert(
I.isBitwiseLogicOp() &&
"Unexpected opcode for bitwise logic folding");
1757 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1763 auto FoldBitwiseICmpZeroWithICmp = [&](
Value *Op0,
1778 auto *ICmpR = cast<ZExtInst>(Op1)->getOperand(0);
1784 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op0, Op1))
1787 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op1, Op0))
1790 CastInst *Cast0 = dyn_cast<CastInst>(Op0);
1796 Type *DestTy =
I.getType();
1804 CastInst *Cast1 = dyn_cast<CastInst>(Op1);
1821 unsigned XNumBits =
X->getType()->getScalarSizeInBits();
1822 unsigned YNumBits =
Y->getType()->getScalarSizeInBits();
1823 if (XNumBits < YNumBits)
1841 shouldOptimizeCast(Cast0) && shouldOptimizeCast(Cast1)) {
1852 assert(
I.getOpcode() == Instruction::And);
1853 Value *Op0 =
I.getOperand(0);
1854 Value *Op1 =
I.getOperand(1);
1862 return BinaryOperator::CreateXor(
A,
B);
1878 assert(
I.getOpcode() == Instruction::Or);
1879 Value *Op0 =
I.getOperand(0);
1880 Value *Op1 =
I.getOperand(1);
1905 return BinaryOperator::CreateXor(
A,
B);
1925 Value *Op0 =
And.getOperand(0), *Op1 =
And.getOperand(1);
1939 if (!isa<VectorType>(Ty) && !shouldChangeType(Ty,
X->getType()))
1946 if (Opc == Instruction::LShr || Opc == Instruction::Shl)
1963 assert(Opcode == Instruction::And || Opcode == Instruction::Or);
1967 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1969 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1976 const auto matchNotOrAnd =
1977 [Opcode, FlippedOpcode](
Value *
Op,
auto m_A,
auto m_B,
auto m_C,
1978 Value *&
X,
bool CountUses =
false) ->
bool {
1979 if (CountUses && !
Op->hasOneUse())
1986 return !CountUses ||
X->hasOneUse();
2002 return (Opcode == Instruction::Or)
2012 return (Opcode == Instruction::Or)
2035 if (Opcode == Instruction::Or && Op0->
hasOneUse() &&
2042 Value *
Or = cast<BinaryOperator>(
X)->getOperand(0);
2074 return (Opcode == Instruction::Or)
2076 : BinaryOperator::CreateOr(
Xor,
X);
2110 if (!isa<Constant>(
X) && !isa<Constant>(
Y) && !isa<Constant>(Z)) {
2112 if (!
X->hasOneUse()) {
2117 if (!
Y->hasOneUse()) {
2138 Type *Ty =
I.getType();
2140 Value *Op0 =
I.getOperand(0);
2141 Value *Op1 =
I.getOperand(1);
2153 case Instruction::And:
2154 if (
C->countl_one() < LastOneMath)
2157 case Instruction::Xor:
2158 case Instruction::Or:
2159 if (
C->countl_zero() < LastOneMath)
2168 ConstantInt::get(Ty, *C2), Op0);
2175 assert((
I.isBitwiseLogicOp() ||
I.getOpcode() == Instruction::Add) &&
2176 "Unexpected opcode");
2179 Constant *ShiftedC1, *ShiftedC2, *AddC;
2180 Type *Ty =
I.getType();
2194 auto *Op0Inst = dyn_cast<Instruction>(
I.getOperand(0));
2195 auto *Op1Inst = dyn_cast<Instruction>(
I.getOperand(1));
2196 if (!Op0Inst || !Op1Inst)
2202 if (ShiftOp != Op1Inst->getOpcode())
2206 if (
I.getOpcode() == Instruction::Add && ShiftOp != Instruction::Shl)
2226 assert(
I.isBitwiseLogicOp() &&
"Should and/or/xor");
2227 if (!
I.getOperand(0)->hasOneUse())
2234 if (
Y && (!
Y->hasOneUse() ||
X->getIntrinsicID() !=
Y->getIntrinsicID()))
2240 if (!
Y && (!(IID == Intrinsic::bswap || IID == Intrinsic::bitreverse) ||
2245 case Intrinsic::fshl:
2246 case Intrinsic::fshr: {
2247 if (
X->getOperand(2) !=
Y->getOperand(2))
2250 Builder.
CreateBinOp(
I.getOpcode(),
X->getOperand(0),
Y->getOperand(0));
2252 Builder.
CreateBinOp(
I.getOpcode(),
X->getOperand(1),
Y->getOperand(1));
2256 case Intrinsic::bswap:
2257 case Intrinsic::bitreverse: {
2259 I.getOpcode(),
X->getOperand(0),
2260 Y ?
Y->getOperand(0)
2261 : ConstantInt::get(
I.getType(), IID == Intrinsic::bswap
2280 unsigned Depth = 0) {
2287 auto *
I = dyn_cast<BinaryOperator>(V);
2288 if (!
I || !
I->isBitwiseLogicOp() ||
Depth >= 3)
2291 if (!
I->hasOneUse())
2292 SimplifyOnly =
true;
2295 SimplifyOnly, IC,
Depth + 1);
2297 SimplifyOnly, IC,
Depth + 1);
2298 if (!NewOp0 && !NewOp1)
2302 NewOp0 =
I->getOperand(0);
2304 NewOp1 =
I->getOperand(1);
2319 Type *Ty =
I.getType();
2353 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2388 Constant *NewC = ConstantInt::get(Ty, *
C & *XorC);
2391 return BinaryOperator::CreateXor(
And, NewC);
2402 APInt Together = *
C & *OrC;
2405 return BinaryOperator::CreateOr(
And, ConstantInt::get(Ty, Together));
2409 const APInt *ShiftC;
2411 ShiftC->
ult(Width)) {
2416 Constant *ShAmtC = ConstantInt::get(Ty, ShiftC->
zext(Width));
2417 return BinaryOperator::CreateLShr(Sext, ShAmtC);
2425 return BinaryOperator::CreateLShr(
X, ConstantInt::get(Ty, *ShiftC));
2433 if (Op0->
hasOneUse() &&
C->isPowerOf2() && (*AddC & (*
C - 1)) == 0) {
2434 assert((*
C & *AddC) != 0 &&
"Expected common bit");
2436 return BinaryOperator::CreateXor(NewAnd, Op1);
2443 switch (
B->getOpcode()) {
2444 case Instruction::Xor:
2445 case Instruction::Or:
2446 case Instruction::Mul:
2447 case Instruction::Add:
2448 case Instruction::Sub:
2464 C->isIntN(
X->getType()->getScalarSizeInBits())) {
2465 unsigned XWidth =
X->getType()->getScalarSizeInBits();
2466 Constant *TruncC1 = ConstantInt::get(
X->getType(), C1->
trunc(XWidth));
2470 Constant *TruncC = ConstantInt::get(
X->getType(),
C->trunc(XWidth));
2480 C->isMask(
X->getType()->getScalarSizeInBits())) {
2490 C->isMask(
X->getType()->getScalarSizeInBits())) {
2524 if (
C->isPowerOf2() &&
2527 int Log2C =
C->exactLogBase2();
2529 cast<BinaryOperator>(Op0)->getOpcode() == Instruction::Shl;
2530 int BitNum = IsShiftLeft ? Log2C - Log2ShiftC : Log2ShiftC - Log2C;
2531 assert(BitNum >= 0 &&
"Expected demanded bits to handle impossible mask");
2564 if (Cmp && Cmp->isZeroValue()) {
2589 Attribute::NoImplicitFloat)) {
2605 X->getType()->getScalarSizeInBits())))) {
2607 return BinaryOperator::CreateAnd(SExt, Op1);
2613 if (
I.getType()->isIntOrIntVectorTy(1)) {
2614 if (
auto *SI0 = dyn_cast<SelectInst>(Op0)) {
2616 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
true))
2619 if (
auto *SI1 = dyn_cast<SelectInst>(Op1)) {
2621 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
true))
2636 return BinaryOperator::CreateAnd(Op0,
B);
2639 return BinaryOperator::CreateAnd(Op1,
B);
2647 if (NotC !=
nullptr)
2648 return BinaryOperator::CreateAnd(Op0, NotC);
2657 if (NotC !=
nullptr)
2667 return BinaryOperator::CreateAnd(
A,
B);
2675 return BinaryOperator::CreateAnd(
A,
B);
2704 bool IsLogical = isa<SelectInst>(Op1);
2706 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
2708 foldAndOrOfICmps(
LHS, Cmp,
I,
true, IsLogical))
2713 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
2714 if (
Value *Res = foldAndOrOfICmps(
LHS, Cmp,
I,
true,
2721 bool IsLogical = isa<SelectInst>(Op0);
2723 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
2725 foldAndOrOfICmps(Cmp,
RHS,
I,
true, IsLogical))
2730 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
2731 if (
Value *Res = foldAndOrOfICmps(Cmp,
RHS,
I,
true,
2739 if (
FCmpInst *
LHS = dyn_cast<FCmpInst>(
I.getOperand(0)))
2740 if (
FCmpInst *
RHS = dyn_cast<FCmpInst>(
I.getOperand(1)))
2741 if (
Value *Res = foldLogicOfFCmps(
LHS,
RHS,
true))
2747 if (
Instruction *CastedAnd = foldCastedBitwiseLogic(
I))
2760 A->getType()->isIntOrIntVectorTy(1))
2766 A->getType()->isIntOrIntVectorTy(1))
2771 A->getType()->isIntOrIntVectorTy(1))
2778 if (
A->getType()->isIntOrIntVectorTy(1))
2791 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2800 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2811 Value *Start =
nullptr, *Step =
nullptr;
2819 return Canonicalized;
2821 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
2833 return BinaryOperator::CreateAnd(V, Op1);
2837 return BinaryOperator::CreateAnd(Op0, V);
2844 bool MatchBitReversals) {
2852 for (
auto *Inst : Insts)
2857std::optional<std::pair<Intrinsic::ID, SmallVector<Value *, 3>>>
2861 assert(
Or.getOpcode() == BinaryOperator::Or &&
"Expecting or instruction");
2863 unsigned Width =
Or.getType()->getScalarSizeInBits();
2868 return std::nullopt;
2875 if (isa<BinaryOperator>(Or0) && isa<BinaryOperator>(Or1)) {
2876 Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
2882 return std::nullopt;
2885 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2891 Or1->
getOpcode() == BinaryOperator::LShr &&
2892 "Illegal or(shift,shift) pair");
2896 auto matchShiftAmount = [&](
Value *L,
Value *R,
unsigned Width) ->
Value * {
2900 if (
LI->ult(Width) && RI->
ult(Width) && (*
LI + *RI) == Width)
2901 return ConstantInt::get(L->getType(), *
LI);
2925 if (ShVal0 != ShVal1)
2936 unsigned Mask = Width - 1;
2960 Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, Width);
2962 ShAmt = matchShiftAmount(ShAmt1, ShAmt0, Width);
2966 return std::nullopt;
2968 FShiftArgs = {ShVal0, ShVal1, ShAmt};
2969 }
else if (isa<ZExtInst>(Or0) || isa<ZExtInst>(Or1)) {
2981 if (!isa<ZExtInst>(Or1))
2985 const APInt *ZextHighShlAmt;
2988 return std::nullopt;
2992 return std::nullopt;
2994 unsigned HighSize =
High->getType()->getScalarSizeInBits();
2995 unsigned LowSize =
Low->getType()->getScalarSizeInBits();
2998 if (ZextHighShlAmt->
ult(LowSize) || ZextHighShlAmt->
ugt(Width - HighSize))
2999 return std::nullopt;
3006 if (!isa<ZExtInst>(
Y))
3009 const APInt *ZextLowShlAmt;
3016 if (*ZextLowShlAmt + *ZextHighShlAmt != Width)
3022 ZextLowShlAmt->
ule(Width - LowSize) &&
"Invalid concat");
3024 FShiftArgs = {U, U, ConstantInt::get(Or0->
getType(), *ZextHighShlAmt)};
3029 if (FShiftArgs.
empty())
3030 return std::nullopt;
3032 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
3033 return std::make_pair(IID, FShiftArgs);
3039 auto [IID, FShiftArgs] = *Opt;
3050 assert(
Or.getOpcode() == Instruction::Or &&
"bswap requires an 'or'");
3051 Value *Op0 =
Or.getOperand(0), *Op1 =
Or.getOperand(1);
3055 if ((Width & 1) != 0)
3057 unsigned HalfWidth = Width / 2;
3060 if (!isa<ZExtInst>(Op0))
3064 Value *LowerSrc, *ShlVal, *UpperSrc;
3077 NewUpper = Builder.
CreateShl(NewUpper, HalfWidth);
3085 Value *LowerBSwap, *UpperBSwap;
3088 return ConcatIntrinsicCalls(Intrinsic::bswap, UpperBSwap, LowerBSwap);
3092 Value *LowerBRev, *UpperBRev;
3095 return ConcatIntrinsicCalls(Intrinsic::bitreverse, UpperBRev, LowerBRev);
3102 unsigned NumElts = cast<FixedVectorType>(C1->
getType())->getNumElements();
3103 for (
unsigned i = 0; i != NumElts; ++i) {
3106 if (!EltC1 || !EltC2)
3125 Type *Ty =
A->getType();
3141 if (
A->getType()->isIntOrIntVectorTy()) {
3143 if (NumSignBits ==
A->getType()->getScalarSizeInBits() &&
3166 Cond->getType()->isIntOrIntVectorTy(1)) {
3192 Cond->getType()->isIntOrIntVectorTy(1) &&
3206 Value *
D,
bool InvertFalseVal) {
3209 Type *OrigType =
A->getType();
3212 if (
Value *
Cond = getSelectCondition(
A,
C, InvertFalseVal)) {
3217 Type *SelTy =
A->getType();
3218 if (
auto *VecTy = dyn_cast<VectorType>(
Cond->getType())) {
3220 unsigned Elts = VecTy->getElementCount().getKnownMinValue();
3241 bool IsAnd,
bool IsLogical,
3248 IsAnd ?
LHS->getInversePredicate() :
LHS->getPredicate();
3250 IsAnd ?
RHS->getInversePredicate() :
RHS->getPredicate();
3259 auto MatchRHSOp = [LHS0, CInt](
const Value *RHSOp) {
3262 (CInt->
isZero() && RHSOp == LHS0);
3293 if (
Value *V = foldAndOrOfICmpsOfAndWithPow2(LHS, RHS, &
I, IsAnd, IsLogical))
3297 Value *LHS0 =
LHS->getOperand(0), *RHS0 =
RHS->getOperand(0);
3298 Value *LHS1 =
LHS->getOperand(1), *RHS1 =
RHS->getOperand(1);
3300 const APInt *LHSC =
nullptr, *RHSC =
nullptr;
3307 if (LHS0 == RHS1 && LHS1 == RHS0) {
3311 if (LHS0 == RHS0 && LHS1 == RHS1) {
3314 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
3363 if (IsAnd && !IsLogical)
3381 if (
Value *
X = foldEqOfParts(LHS, RHS, IsAnd))
3421 const APInt *AndC, *SmallC =
nullptr, *BigC =
nullptr;
3435 if (SmallC && BigC) {
3436 unsigned BigBitSize = BigC->getBitWidth();
3455 bool TrueIfSignedL, TrueIfSignedR;
3461 if ((TrueIfSignedL && !TrueIfSignedR &&
3464 (!TrueIfSignedL && TrueIfSignedR &&
3471 if ((TrueIfSignedL && !TrueIfSignedR &&
3474 (!TrueIfSignedL && TrueIfSignedR &&
3483 return foldAndOrOfICmpsUsingRanges(LHS, RHS, IsAnd);
3488 assert(
I.getOpcode() == Instruction::Or &&
3489 "Simplification only supports or at the moment.");
3491 Value *Cmp1, *Cmp2, *Cmp3, *Cmp4;
3543 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
3544 Type *Ty =
I.getType();
3546 if (
auto *SI0 = dyn_cast<SelectInst>(Op0)) {
3548 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
false))
3551 if (
auto *SI1 = dyn_cast<SelectInst>(Op1)) {
3553 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
false))
3584 return BinaryOperator::CreateXor(
Or, ConstantInt::get(Ty, *CV));
3592 return BinaryOperator::CreateMul(
X, IncrementY);
3601 const APInt *C0, *C1;
3620 if ((*C0 & *C1).
isZero()) {
3625 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
3626 return BinaryOperator::CreateAnd(
A, C01);
3632 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
3633 return BinaryOperator::CreateAnd(
B, C01);
3637 const APInt *C2, *C3;
3642 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
3643 return BinaryOperator::CreateAnd(
Or, C01);
3653 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D))
3655 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B))
3657 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D))
3659 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B))
3661 if (
Value *V = matchSelectFromAndOr(
B,
D,
A,
C))
3663 if (
Value *V = matchSelectFromAndOr(
B,
D,
C,
A))
3665 if (
Value *V = matchSelectFromAndOr(
D,
B,
A,
C))
3667 if (
Value *V = matchSelectFromAndOr(
D,
B,
C,
A))
3676 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D,
true))
3678 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B,
true))
3680 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D,
true))
3682 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B,
true))
3691 return BinaryOperator::CreateOr(Op0,
C);
3698 return BinaryOperator::CreateOr(Op1,
C);
3704 bool SwappedForXor =
false;
3707 SwappedForXor =
true;
3714 return BinaryOperator::CreateOr(Op0,
B);
3716 return BinaryOperator::CreateOr(Op0,
A);
3721 return BinaryOperator::CreateOr(
A,
B);
3749 return BinaryOperator::CreateOr(Nand,
C);
3767 bool IsLogical = isa<SelectInst>(Op1);
3769 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
3771 foldAndOrOfICmps(
LHS, Cmp,
I,
false, IsLogical))
3776 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
3777 if (
Value *Res = foldAndOrOfICmps(
LHS, Cmp,
I,
false,
3784 bool IsLogical = isa<SelectInst>(Op0);
3786 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
3788 foldAndOrOfICmps(Cmp,
RHS,
I,
false, IsLogical))
3793 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
3794 if (
Value *Res = foldAndOrOfICmps(Cmp,
RHS,
I,
false,
3802 if (
FCmpInst *
LHS = dyn_cast<FCmpInst>(
I.getOperand(0)))
3803 if (
FCmpInst *
RHS = dyn_cast<FCmpInst>(
I.getOperand(1)))
3804 if (
Value *Res = foldLogicOfFCmps(
LHS,
RHS,
false))
3822 A->getType()->isIntOrIntVectorTy(1))
3835 return BinaryOperator::CreateOr(Inner, CI);
3842 Value *
X =
nullptr, *
Y =
nullptr;
3874 return BinaryOperator::CreateXor(
A,
B);
3890 Value *
Mul, *Ov, *MulIsNotZero, *UMulWithOv;
3907 if (
match(UMulWithOv, m_Intrinsic<Intrinsic::umul_with_overflow>(
3911 return BinaryOperator::CreateAnd(NotNullA, NotNullB);
3920 const APInt *C1, *C2;
3936 : C2->
uadd_ov(*C1, Overflow));
3940 return BinaryOperator::CreateOr(Ov, NewCmp);
3960 Value *Start =
nullptr, *Step =
nullptr;
3978 return BinaryOperator::CreateOr(
3990 return BinaryOperator::CreateOr(
3998 return Canonicalized;
4000 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
4021 Attribute::NoImplicitFloat)) {
4034 if ((KnownX.
One & *C2) == *C2)
4035 return BinaryOperator::CreateAnd(
X, ConstantInt::get(Ty, *C1 | *C2));
4044 return BinaryOperator::CreateOr(V, Op1);
4048 return BinaryOperator::CreateOr(Op0, V);
4050 if (cast<PossiblyDisjointInst>(
I).isDisjoint())
4061 assert(
I.getOpcode() == Instruction::Xor);
4062 Value *Op0 =
I.getOperand(0);
4063 Value *Op1 =
I.getOperand(1);
4074 return BinaryOperator::CreateXor(
A,
B);
4082 return BinaryOperator::CreateXor(
A,
B);
4090 return BinaryOperator::CreateXor(
A,
B);
4112 assert(
I.getOpcode() == Instruction::Xor &&
I.getOperand(0) == LHS &&
4113 I.getOperand(1) == RHS &&
"Should be 'xor' with these operands");
4116 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
4117 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
4120 if (LHS0 == RHS1 && LHS1 == RHS0) {
4124 if (LHS0 == RHS0 && LHS1 == RHS1) {
4127 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
4135 const APInt *LC, *RC;
4144 bool TrueIfSignedL, TrueIfSignedR;
4160 if (CRUnion && CRIntersect)
4161 if (
auto CR = CRUnion->exactIntersectWith(CRIntersect->inverse())) {
4162 if (CR->isFullSet())
4164 if (CR->isEmptySet())
4169 CR->getEquivalentICmp(NewPred, NewC,
Offset);
4178 ConstantInt::get(Ty, NewC));
4196 if (OrICmp == LHS && AndICmp == RHS) {
4201 if (OrICmp == RHS && AndICmp == LHS) {
4208 Y->setPredicate(
Y->getInversePredicate());
4210 if (!
Y->hasOneUse()) {
4221 Y->replaceUsesWithIf(NotY,
4222 [NotY](
Use &U) {
return U.getUser() != NotY; });
4262 return BinaryOperator::CreateXor(NewA,
X);
4268 Type *EltTy =
C->getType()->getScalarType();
4274 return BinaryOperator::CreateOr(
LHS,
RHS);
4289 return A ==
C ||
A ==
D ||
B ==
C ||
B ==
D;
4298 return BinaryOperator::CreateOr(
X, NotY);
4306 return BinaryOperator::CreateOr(
Y, NotX);
4316 assert(
Xor.getOpcode() == Instruction::Xor &&
"Expected an xor instruction.");
4322 Value *Op0 =
Xor.getOperand(0), *Op1 =
Xor.getOperand(1);
4337 auto *
Add = cast<BinaryOperator>(Op0);
4338 Value *NegA =
Add->hasNoUnsignedWrap()
4348 auto *
I = dyn_cast<Instruction>(
Op);
4355 auto *
I = cast<Instruction>(
Op);
4358 Op->replaceUsesWithIf(NotOp,
4359 [NotOp](
Use &U) {
return U.getUser() != NotOp; });
4381 bool IsBinaryOp = isa<BinaryOperator>(
I);
4421 bool IsBinaryOp = isa<BinaryOperator>(
I);
4423 Value *NotOp0 =
nullptr;
4424 Value *NotOp1 =
nullptr;
4425 Value **OpToInvert =
nullptr;
4470 Type *Ty =
I.getType();
4474 return BinaryOperator::CreateOr(
X, NotY);
4485 return BinaryOperator::CreateAnd(
X, NotY);
4500 return BinaryOperator::CreateAnd(DecX, NotY);
4505 return BinaryOperator::CreateAShr(
X,
Y);
4511 return BinaryOperator::CreateAShr(
X,
Y);
4567 Type *SextTy = cast<BitCastOperator>(NotOp)->getSrcTy();
4573 if (
auto *NotOpI = dyn_cast<Instruction>(NotOp))
4580 auto *
II = dyn_cast<IntrinsicInst>(NotOp);
4581 if (
II &&
II->hasOneUse()) {
4589 if (
II->getIntrinsicID() == Intrinsic::is_fpclass) {
4590 ConstantInt *ClassMask = cast<ConstantInt>(
II->getArgOperand(1));
4592 1, ConstantInt::get(ClassMask->
getType(),
4607 if (
auto *Sel = dyn_cast<SelectInst>(NotOp)) {
4608 Value *TV = Sel->getTrueValue();
4609 Value *FV = Sel->getFalseValue();
4610 auto *CmpT = dyn_cast<CmpInst>(TV);
4611 auto *CmpF = dyn_cast<CmpInst>(FV);
4612 bool InvertibleT = (CmpT && CmpT->hasOneUse()) || isa<Constant>(TV);
4613 bool InvertibleF = (CmpF && CmpF->hasOneUse()) || isa<Constant>(FV);
4614 if (InvertibleT && InvertibleF) {
4616 CmpT->setPredicate(CmpT->getInversePredicate());
4620 CmpF->setPredicate(CmpF->getInversePredicate());
4678 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
4683 return BinaryOperator::CreateDisjointOr(Op0, Op1);
4685 return BinaryOperator::CreateOr(Op0, Op1);
4703 return BinaryOperator::CreateXor(
4726 *CA ==
X->getType()->getScalarSizeInBits() - 1 &&
4734 Type *Ty =
I.getType();
4742 return BinaryOperator::CreateSub(ConstantInt::get(Ty, *
C + *RHSC),
X);
4746 return BinaryOperator::CreateAdd(
X, ConstantInt::get(Ty, *
C + *RHSC));
4751 return BinaryOperator::CreateXor(
X, ConstantInt::get(Ty, *
C ^ *RHSC));
4756 auto *
II = dyn_cast<IntrinsicInst>(Op0);
4759 if ((IID == Intrinsic::ctlz || IID == Intrinsic::cttz) &&
4762 IID = (IID == Intrinsic::ctlz) ? Intrinsic::cttz : Intrinsic::ctlz;
4774 return BinaryOperator::CreateShl(NotX, ConstantInt::get(Ty, *
C));
4780 return BinaryOperator::CreateLShr(NotX, ConstantInt::get(Ty, *
C));
4799 Attribute::NoImplicitFloat)) {
4823 return BinaryOperator::CreateXor(Opnd0, ConstantInt::get(Ty, FoldConst));
4856 return BinaryOperator::CreateXor(
4862 return BinaryOperator::CreateXor(
4868 return BinaryOperator::CreateOr(
A,
B);
4872 return BinaryOperator::CreateOr(
A,
B);
4882 return BinaryOperator::CreateOr(
A,
B);
4897 if (
B ==
C ||
B ==
D)
4908 if (
I.getType()->isIntOrIntVectorTy(1) &&
4911 bool NeedFreeze = isa<SelectInst>(Op0) && isa<SelectInst>(Op1) &&
B ==
D;
4912 if (
B ==
C ||
B ==
D)
4924 if (
auto *
LHS = dyn_cast<ICmpInst>(
I.getOperand(0)))
4925 if (
auto *
RHS = dyn_cast<ICmpInst>(
I.getOperand(1)))
4929 if (
Instruction *CastedXor = foldCastedBitwiseLogic(
I))
4949 return Canonicalized;
4951 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
4954 if (
Instruction *Folded = canonicalizeConditionalNegationViaMathToSelect(
I))
amdgpu AMDGPU Register Bank Select
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static bool isSigned(unsigned int Opcode)
static unsigned conjugateICmpMask(unsigned Mask)
Convert an analysis of a masked ICmp into its equivalent if all boolean operations had the opposite s...
static Instruction * foldNotXor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static bool matchIsFPClassLikeFCmp(Value *Op, Value *&ClassVal, uint64_t &ClassMask)
Match an fcmp against a special value that performs a test possible by llvm.is.fpclass.
static Value * foldSignedTruncationCheck(ICmpInst *ICmp0, ICmpInst *ICmp1, Instruction &CxtI, InstCombiner::BuilderTy &Builder)
General pattern: X & Y.
static Instruction * visitMaskedMerge(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
If we have a masked merge, in the canonical form of: (assuming that A only has one use....
static Instruction * canonicalizeAbs(BinaryOperator &Xor, InstCombiner::BuilderTy &Builder)
Canonicalize a shifty way to code absolute value to the more common pattern that uses negation and se...
static Value * foldUnsignedUnderflowCheck(ICmpInst *ZeroICmp, ICmpInst *UnsignedICmp, bool IsAnd, const SimplifyQuery &Q, InstCombiner::BuilderTy &Builder)
Commuted variants are assumed to be handled by calling this function again with the parameters swappe...
static Instruction * foldOrToXor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static Value * simplifyAndOrWithOpReplaced(Value *V, Value *Op, Value *RepOp, bool SimplifyOnly, InstCombinerImpl &IC, unsigned Depth=0)
static Instruction * matchDeMorgansLaws(BinaryOperator &I, InstCombiner &IC)
Match variations of De Morgan's Laws: (~A & ~B) == (~(A | B)) (~A | ~B) == (~(A & B))
static Value * 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 * foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, Value *A, Value *B, Value *D, Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR, InstCombiner::BuilderTy &Builder)
Try to fold (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E) into a single (icmp(A & X) ==/!...
static Value * getNewICmpValue(unsigned Code, bool Sign, Value *LHS, Value *RHS, InstCombiner::BuilderTy &Builder)
This is the complement of getICmpCode, which turns an opcode and two operands into either a constant ...
static std::optional< std::pair< unsigned, unsigned > > getMaskedTypeForICmpPair(Value *&A, Value *&B, Value *&C, Value *&D, Value *&E, ICmpInst *LHS, ICmpInst *RHS, ICmpInst::Predicate &PredL, ICmpInst::Predicate &PredR)
Handle (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E).
static Value * extractIntPart(const IntPart &P, IRBuilderBase &Builder)
Materialize an extraction of bits from an integer in IR.
static bool matchUnorderedInfCompare(FCmpInst::Predicate P, Value *LHS, Value *RHS)
Matches fcmp u__ x, +/-inf.
static Instruction * matchOrConcat(Instruction &Or, InstCombiner::BuilderTy &Builder)
Attempt to combine or(zext(x),shl(zext(y),bw/2) concat packing patterns.
static bool matchIsNotNaN(FCmpInst::Predicate P, Value *LHS, Value *RHS)
Matches canonical form of isnan, fcmp ord x, 0.
static bool areInverseVectorBitmasks(Constant *C1, Constant *C2)
If all elements of two constant vectors are 0/-1 and inverses, return true.
MaskedICmpType
Classify (icmp eq (A & B), C) and (icmp ne (A & B), C) as matching patterns that can be simplified.
static Instruction * foldComplexAndOrPatterns(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
Try folding relatively complex patterns for both And and Or operations with all And and Or swapped.
static Value * getFCmpValue(unsigned Code, Value *LHS, Value *RHS, InstCombiner::BuilderTy &Builder)
This is the complement of getFCmpCode, which turns an opcode and two operands into either a FCmp inst...
static Value * foldOrOfInversions(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static Instruction * matchFunnelShift(Instruction &Or, InstCombinerImpl &IC)
Match UB-safe variants of the funnel shift intrinsic.
static Instruction * reassociateForUses(BinaryOperator &BO, InstCombinerImpl::BuilderTy &Builder)
Try to reassociate a pair of binops so that values with one use only are part of the same instruction...
static Value * foldAndOrOfICmpsWithPow2AndWithZero(InstCombiner::BuilderTy &Builder, ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, const SimplifyQuery &Q)
static Instruction * foldBitwiseLogicWithIntrinsics(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static Value * foldAndOrOfICmpsWithConstEq(ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd, bool IsLogical, InstCombiner::BuilderTy &Builder, const SimplifyQuery &Q)
Reduce logic-of-compares with equality to a constant by substituting a common operand with the consta...
This file provides internal interfaces used to implement the InstCombine.
This file provides the interface for the instcombine pass implementation.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
uint64_t IntrinsicInst * II
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static constexpr int Concat[]
support::ulittle16_t & Lo
support::ulittle16_t & Hi
bool bitwiseIsEqual(const APFloat &RHS) const
APInt bitcastToAPInt() const
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
APInt trunc(unsigned width) const
Truncate to new width.
unsigned countLeadingOnes() const
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
APInt usub_ov(const APInt &RHS, bool &Overflow) const
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isSignMask() const
Check if the APInt's value is returned by getSignMask.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
APInt sadd_ov(const APInt &RHS, bool &Overflow) const
bool intersects(const APInt &RHS) const
This operation tests if there are any pairs of corresponding bits between this APInt and RHS that are...
int32_t exactLogBase2() const
APInt reverseBits() const
APInt uadd_ov(const APInt &RHS, bool &Overflow) const
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countLeadingZeros() const
bool ule(const APInt &RHS) const
Unsigned less or equal comparison.
APInt shl(unsigned shiftAmt) const
Left-shift function.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
APInt ssub_ov(const APInt &RHS, bool &Overflow) const
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
void clearSignBit()
Set the sign bit to 0.
const Function * getParent() const
Return the enclosing method, or null if none.
bool isSigned() const
Whether the intrinsic is signed or unsigned.
Instruction::BinaryOps getBinaryOp() const
Returns the binary operation underlying the intrinsic.
BinaryOps getOpcode() const
static BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
static BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
static BinaryOperator * CreateWithCopiedFlags(BinaryOps Opc, Value *V1, Value *V2, Value *CopyO, const Twine &Name="", InsertPosition InsertBefore=nullptr)
This class represents a no-op cast from one type to another.
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
This is the base class for all instructions that perform data casts.
Type * getSrcTy() const
Return the source type, as a convenience.
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
static CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
Type * getDestTy() const
Return the destination type, as a convenience.
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ ICMP_ULT
unsigned less than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ ICMP_SGE
signed greater or equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Predicate getOrderedPredicate() const
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Predicate getPredicate() const
Return the predicate for this instruction.
static bool isUnordered(Predicate predicate)
Determine if the predicate is an unordered operation.
static Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getNot(Constant *C)
static Constant * getXor(Constant *C1, Constant *C2)
static Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getExactLogBase2(Constant *C)
If C is a scalar/fixed width vector of known powers of 2, then this function returns a new scalar/fix...
static Constant * getZero(Type *Ty, bool Negative=false)
This is the shared class of boolean and integer constants.
bool isMinusOne() const
This function will return true iff every bit in this constant is set to true.
static ConstantInt * getTrue(LLVMContext &Context)
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static ConstantInt * getFalse(LLVMContext &Context)
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
const APInt & getValue() const
Return the constant as an APInt value reference.
This class represents a range of values.
std::optional< ConstantRange > exactUnionWith(const ConstantRange &CR) const
Union the two ranges and return the result if it can be represented exactly, otherwise return std::nu...
ConstantRange subtract(const APInt &CI) const
Subtract the specified constant from the endpoints of this constant range.
const APInt & getLower() const
Return the lower value for this range.
bool isWrappedSet() const
Return true if this set wraps around the unsigned domain.
const APInt & getUpper() const
Return the upper value for this range.
static ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)
Produce the exact range such that all values in the returned range satisfy the given predicate with a...
std::optional< ConstantRange > exactIntersectWith(const ConstantRange &CR) const
Intersect the two ranges and return the result if it can be represented exactly, otherwise return std...
This is an important base class in LLVM.
static Constant * replaceUndefsWith(Constant *C, Constant *Replacement)
Try to replace undefined constant C or undefined elements in C with Replacement.
static Constant * mergeUndefsWith(Constant *C, Constant *Other)
Merges undefs of a Constant with another Constant, along with the undefs already present.
static Constant * getAllOnesValue(Type *Ty)
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
bool isZeroValue() const
Return true if the value is negative zero or null value.
This class represents an Operation in the Expression.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
This instruction compares its operands according to the predicate given to the constructor.
Convenience struct for specifying and reasoning about fast-math flags.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
This instruction compares its operands according to the predicate given to the constructor.
Predicate getSignedPredicate() const
For example, EQ->EQ, SLE->SLE, UGT->SGT, etc.
bool isEquality() const
Return true if this predicate is either EQ or NE.
Common base class shared among various IRBuilders.
CallInst * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with 1 operand which is mangled on its type.
Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with 2 operands which is mangled on the first type.
Value * CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateLogicalOp(Instruction::BinaryOps Opc, Value *Cond1, Value *Cond2, const Twine &Name="")
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
Value * CreateICmpSGT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
ConstantInt * getTrue()
Get the constant value for i1 true.
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateFreeze(Value *V, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateIsNotNeg(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg > -1.
BasicBlock * GetInsertBlock() const
void setFastMathFlags(FastMathFlags NewFMF)
Set the fast-math flags to be used with generated fp-math operators.
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateIsNeg(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg < 0.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateICmpUGT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateLogicalAnd(Value *Cond1, Value *Cond2, const Twine &Name="")
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="")
Value * CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateIsNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg == 0.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateLogicalOr(Value *Cond1, Value *Cond2, const Twine &Name="")
Value * CreateFNeg(Value *V, const Twine &Name="", MDNode *FPMathTag=nullptr)
Instruction * canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(BinaryOperator &I)
Instruction * foldBinOpIntoSelectOrPhi(BinaryOperator &I)
This is a convenience wrapper function for the above two functions.
Instruction * visitOr(BinaryOperator &I)
bool SimplifyAssociativeOrCommutative(BinaryOperator &I)
Performs a few simplifications for operators which are associative or commutative.
Value * foldUsingDistributiveLaws(BinaryOperator &I)
Tries to simplify binary operations which some other binary operation distributes over.
Instruction * foldBinOpShiftWithShift(BinaryOperator &I)
Value * insertRangeTest(Value *V, const APInt &Lo, const APInt &Hi, bool isSigned, bool Inside)
Emit a computation of: (V >= Lo && V < Hi) if Inside is true, otherwise (V < Lo || V >= Hi).
bool sinkNotIntoLogicalOp(Instruction &I)
std::optional< std::pair< Intrinsic::ID, SmallVector< Value *, 3 > > > convertOrOfShiftsToFunnelShift(Instruction &Or)
Constant * getLosslessUnsignedTrunc(Constant *C, Type *TruncTy)
Instruction * visitAnd(BinaryOperator &I)
bool sinkNotIntoOtherHandOfLogicalOp(Instruction &I)
Instruction * foldBinopWithPhiOperands(BinaryOperator &BO)
For a binary operator with 2 phi operands, try to hoist the binary operation before the phi.
Value * simplifyRangeCheck(ICmpInst *Cmp0, ICmpInst *Cmp1, bool Inverted)
Try to fold a signed range checked with lower bound 0 to an unsigned icmp.
Instruction * tryFoldInstWithCtpopWithNot(Instruction *I)
Value * SimplifyAddWithRemainder(BinaryOperator &I)
Tries to simplify add operations using the definition of remainder.
Constant * getLosslessSignedTrunc(Constant *C, Type *TruncTy)
Instruction * visitXor(BinaryOperator &I)
bool SimplifyDemandedInstructionBits(Instruction &Inst)
Tries to simplify operands to an integer instruction based on its demanded bits.
Instruction * foldVectorBinop(BinaryOperator &Inst)
Canonicalize the position of binops relative to shufflevector.
Instruction * matchBSwapOrBitReverse(Instruction &I, bool MatchBSwaps, bool MatchBitReversals)
Given an initial instruction, check to see if it is the root of a bswap/bitreverse idiom.
void freelyInvertAllUsersOf(Value *V, Value *IgnoredUser=nullptr)
Freely adapt every user of V as-if V was changed to !V.
The core instruction combiner logic.
bool isFreeToInvert(Value *V, bool WillInvertAllUses, bool &DoesConsume)
Return true if the specified value is free to invert (apply ~ to).
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, unsigned Depth=0, const Instruction *CxtI=nullptr)
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
InstructionWorklist & Worklist
A worklist of the instructions that need to be simplified.
unsigned ComputeNumSignBits(const Value *Op, unsigned Depth=0, const Instruction *CxtI=nullptr) const
static Value * peekThroughBitcast(Value *V, bool OneUseOnly=false)
Return the source operand of a potentially bitcasted value while optionally checking if it has one us...
bool canFreelyInvertAllUsersOf(Instruction *V, Value *IgnoredUser)
Given i1 V, can every user of V be freely adapted if V is changed to !V ? InstCombine's freelyInvertA...
void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth, const Instruction *CxtI) const
bool MaskedValueIsZero(const Value *V, const APInt &Mask, unsigned Depth=0, const Instruction *CxtI=nullptr) const
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
const SimplifyQuery & getSimplifyQuery() const
void pushUsersToWorkList(Instruction &I)
When an instruction is simplified, add all users of the instruction to the work lists because they mi...
void push(Instruction *I)
Push the instruction onto the worklist stack.
void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
A wrapper class for inspecting calls to intrinsic functions.
This class represents a sign extension of integer types.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, Instruction *MDFrom=nullptr)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
const fltSemantics & getFltSemantics() const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isIEEE() const
Return whether the type is IEEE compatible, as defined by the eponymous method in APFloat.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isIEEELikeFPTy() const
Return true if this is a well-behaved IEEE-like type, which has a IEEE compatible layout as defined b...
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
iterator_range< user_iterator > users()
bool hasNUsesOrMore(unsigned N) const
Return true if this value has N uses or more.
bool hasNUses(unsigned N) const
Return true if this Value has exactly N uses.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
static VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
Represents an op.with.overflow intrinsic.
This class represents zero extension of integer types.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const APInt & umin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be unsigned.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
cst_pred_ty< is_lowbit_mask > m_LowBitMask()
Match an integer or vector with only the low bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
cst_pred_ty< is_negative > m_Negative()
Match an integer or vector of negative values.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
cst_pred_ty< is_sign_mask > m_SignMask()
Match an integer or vector with only the sign bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
cstfp_pred_ty< is_inf > m_Inf()
Match a positive or negative infinity FP constant.
m_Intrinsic_Ty< Opnd0 >::Ty m_BitReverse(const Opnd0 &Op0)
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power-of-2.
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.
constantexpr_match m_ConstantExpr()
Match a constant expression or a constant that contains a constant expression.
specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)
cst_pred_ty< is_nonnegative > m_NonNegative()
Match an integer or vector of non-negative values.
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
match_combine_or< CastInst_match< OpTy, SExtInst >, OpTy > m_SExtOrSelf(const OpTy &Op)
BinOpPred_match< LHS, RHS, is_logical_shift_op > m_LogicalShift(const LHS &L, const RHS &R)
Matches logical shift operations.
match_combine_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)
Combine two pattern matchers matching L && R.
CmpClass_match< LHS, RHS, FCmpInst, FCmpInst::Predicate > m_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R)
bind_ty< WithOverflowInst > m_WithOverflowInst(WithOverflowInst *&I)
Match a with overflow intrinsic, capturing it if we match.
BinaryOp_match< LHS, RHS, Instruction::Xor, true > m_c_Xor(const LHS &L, const RHS &R)
Matches an Xor with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
cst_pred_ty< is_zero_int > m_ZeroInt()
Match an integer 0 or a vector with all elements equal to 0.
apint_match m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate > m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)
OneUse_match< T > m_OneUse(const T &SubPattern)
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
BinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub > m_Neg(const ValTy &V)
Matches a 'Neg' as 'sub 0, V'.
match_combine_and< class_match< Constant >, match_unless< constantexpr_match > > m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
cst_pred_ty< is_negated_power2 > m_NegatedPower2()
Match a integer or vector negated power-of-2.
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate, true > m_c_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
DisjointOr_match< LHS, RHS, true > m_c_DisjointOr(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
apfloat_match m_APFloatAllowPoison(const APFloat *&Res)
Match APFloat while allowing poison in splat vector constants.
match_combine_or< BinaryOp_match< LHS, RHS, Instruction::Add >, DisjointOr_match< LHS, RHS > > m_AddLike(const LHS &L, const RHS &R)
Match either "add" or "or disjoint".
SpecificCmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate > m_SpecificICmp(ICmpInst::Predicate MatchPred, const LHS &L, const RHS &R)
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)
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.
SpecificCmpClass_match< LHS, RHS, FCmpInst, FCmpInst::Predicate > m_SpecificFCmp(FCmpInst::Predicate MatchPred, const LHS &L, const RHS &R)
BinaryOp_match< cst_pred_ty< is_all_ones >, ValTy, Instruction::Xor, true > m_Not(const ValTy &V)
Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
m_Intrinsic_Ty< Opnd0 >::Ty m_BSwap(const Opnd0 &Op0)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
ElementWiseBitCast_match< OpTy > m_ElementWiseBitCast(const OpTy &Op)
m_Intrinsic_Ty< Opnd0 >::Ty m_FAbs(const Opnd0 &Op0)
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_CopySign(const Opnd0 &Op0, const Opnd1 &Op1)
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
match_unless< Ty > m_Unless(const Ty &M)
Match if the inner matcher does NOT match.
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
cst_pred_ty< icmp_pred_with_threshold > m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold)
Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.
NodeAddr< CodeNode * > Code
This is an optimization pass for GlobalISel generic memory operations.
Intrinsic::ID getInverseMinMaxIntrinsic(Intrinsic::ID MinMaxID)
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
Constant * getPredForFCmpCode(unsigned Code, Type *OpTy, CmpInst::Predicate &Pred)
This is the complement of getFCmpCode.
bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS, bool &TrueIfSigned)
Given an exploded icmp instruction, return true if the comparison only checks the sign bit.
bool predicatesFoldable(CmpInst::Predicate P1, CmpInst::Predicate P2)
Return true if both predicates match sign or if at least one of them is an equality comparison (which...
Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Instruction *I=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return true if the given value is known to have exactly one bit set when defined.
Value * simplifyOrInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an Or, fold the result or return null.
Value * simplifyXorInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an Xor, fold the result or return null.
bool isGuaranteedNotToBeUndef(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be undef, but may be poison.
bool matchSimpleRecurrence(const PHINode *P, BinaryOperator *&BO, Value *&Start, Value *&Step)
Attempt to match a simple first order recurrence cycle of the form: iv = phi Ty [Start,...
bool 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.
bool isKnownInversion(const Value *X, const Value *Y)
Return true iff:
Value * simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an ICmpInst, fold the result or return null.
bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
bool isKnownNegative(const Value *V, const SimplifyQuery &DL, unsigned Depth=0)
Returns true if the given value is known be negative (i.e.
@ Or
Bitwise or logical OR of integers.
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
constexpr unsigned BitWidth
std::pair< Value *, FPClassTest > fcmpToClassTest(CmpInst::Predicate Pred, const Function &F, Value *LHS, Value *RHS, bool LookThroughSrc=true)
Returns a pair of values, which if passed to llvm.is.fpclass, returns the same result as an fcmp with...
APFloat neg(APFloat X)
Returns the negated value of the argument.
bool decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate &Pred, Value *&X, APInt &Mask, bool LookThroughTrunc=true)
Decompose an icmp into the form ((X & Mask) pred 0) if possible.
unsigned getICmpCode(CmpInst::Predicate Pred)
Encode a icmp predicate into a three bit mask.
unsigned getFCmpCode(CmpInst::Predicate CC)
Similar to getICmpCode but for FCmpInst.
Constant * getPredForICmpCode(unsigned Code, bool Sign, Type *OpTy, CmpInst::Predicate &Pred)
This is the complement of getICmpCode.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isNonNegative() const
Returns true if this value is known to be non-negative.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
SimplifyQuery getWithInstruction(const Instruction *I) const