30#define DEBUG_TYPE "instcombine"
45 return Builder.CreateICmp(NewPred,
LHS,
RHS);
55 return Builder.CreateFCmpFMF(NewPred,
LHS,
RHS, FMF);
65 "Lo is not < Hi in range emission code!");
67 Type *Ty = V->getType();
72 if (
isSigned ?
Lo.isMinSignedValue() :
Lo.isMinValue()) {
74 return Builder.CreateICmp(Pred, V, ConstantInt::get(Ty,
Hi));
80 Builder.CreateSub(V, ConstantInt::get(Ty,
Lo), V->getName() +
".off");
82 return Builder.CreateICmp(Pred, VMinusLo, HiMinusLo);
129 const APInt *ConstA =
nullptr, *ConstB =
nullptr, *ConstC =
nullptr;
134 bool IsAPow2 = ConstA && ConstA->
isPowerOf2();
135 bool IsBPow2 = ConstB && ConstB->isPowerOf2();
136 unsigned MaskVal = 0;
137 if (ConstC && ConstC->isZero()) {
156 }
else if (ConstA && ConstC && ConstC->
isSubsetOf(*ConstA)) {
166 }
else if (ConstB && ConstC && ConstC->isSubsetOf(*ConstB)) {
201 Y = ConstantInt::get(
X->getType(), Res->Mask);
202 Z = ConstantInt::get(
X->getType(), Res->C);
211static std::optional<std::pair<unsigned, unsigned>>
224 Value *L1, *L11, *L12, *L2, *L21, *L22;
226 L21 = L22 = L1 =
nullptr;
233 if (!LHSCMP->getOperand(0)->getType()->isIntOrIntVectorTy())
236 PredL = LHSCMP->getPredicate();
237 L1 = LHSCMP->getOperand(0);
238 L2 = LHSCMP->getOperand(1);
259 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
262 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
274 if (!RHSCMP->getOperand(0)->getType()->isIntOrIntVectorTy())
277 PredR = RHSCMP->getPredicate();
279 Value *R1 = RHSCMP->getOperand(0);
280 R2 = RHSCMP->getOperand(1);
289 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
294 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
312 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
316 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
333 }
else if (L12 ==
A) {
336 }
else if (L21 ==
A) {
339 }
else if (L22 ==
A) {
346 return std::optional<std::pair<unsigned, unsigned>>(
347 std::make_pair(LeftType, RightType));
369 const APInt *BCst, *DCst, *OrigECst;
380 APInt ECst = *OrigECst;
386 if (*BCst == 0 || *DCst == 0)
396 !Builder.GetInsertBlock()->getParent()->hasFnAttribute(
397 Attribute::StrictFP)) {
399 if (!Ty->isIEEELikeFPTy())
405 APInt FractionBits = ~ExpBits;
407 if (*BCst != FractionBits)
432 if ((((*BCst & *DCst) & ECst) == 0) &&
433 (*BCst & (*BCst ^ *DCst)).isPowerOf2()) {
434 APInt BorD = *BCst | *DCst;
435 APInt BandBxorDorE = (*BCst & (*BCst ^ *DCst)) | ECst;
436 Value *NewMask = ConstantInt::get(
A->getType(), BorD);
437 Value *NewMaskedValue = ConstantInt::get(
A->getType(), BandBxorDorE);
438 Value *NewAnd = Builder.CreateAnd(
A, NewMask);
439 return Builder.CreateICmp(NewCC, NewAnd, NewMaskedValue);
442 auto IsSubSetOrEqual = [](
const APInt *C1,
const APInt *C2) {
443 return (*C1 & *C2) == *C1;
445 auto IsSuperSetOrEqual = [](
const APInt *C1,
const APInt *C2) {
446 return (*C1 & *C2) == *C2;
455 if (!IsSubSetOrEqual(BCst, DCst) && !IsSuperSetOrEqual(BCst, DCst))
467 if (IsSubSetOrEqual(BCst, DCst))
468 return ConstantInt::get(
LHS->getType(), !IsAnd);
478 if (IsSuperSetOrEqual(BCst, DCst)) {
481 ICmp->setSameSign(
false);
487 assert(IsSubSetOrEqual(BCst, DCst) &&
"Precondition due to above code");
488 if ((*BCst & ECst) != 0) {
491 ICmp->setSameSign(
false);
498 return ConstantInt::get(
LHS->getType(), !IsAnd);
510 "Expected equality predicates for masked type of icmps.");
522 LHS,
RHS, IsAnd,
A,
B,
D,
E, PredL, PredR, Builder)) {
527 RHS,
LHS, IsAnd,
A,
D,
B,
C, PredR, PredL, Builder)) {
540 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *
E =
nullptr;
542 std::optional<std::pair<unsigned, unsigned>> MaskPair =
547 "Expected equality predicates for masked type of icmps.");
548 unsigned LHSMask = MaskPair->first;
549 unsigned RHSMask = MaskPair->second;
550 unsigned Mask = LHSMask & RHSMask;
555 LHS,
RHS, IsAnd,
A,
B,
C,
D,
E, PredL, PredR, LHSMask, RHSMask,
585 Value *NewOr = Builder.CreateOr(
B,
D);
586 Value *NewAnd = Builder.CreateAnd(
A, NewOr);
591 return Builder.CreateICmp(NewCC, NewAnd, Zero);
598 Value *NewOr = Builder.CreateOr(
B,
D);
599 Value *NewAnd = Builder.CreateAnd(
A, NewOr);
600 return Builder.CreateICmp(NewCC, NewAnd, NewOr);
607 Value *NewAnd1 = Builder.CreateAnd(
B,
D);
608 Value *NewAnd2 = Builder.CreateAnd(
A, NewAnd1);
609 return Builder.CreateICmp(NewCC, NewAnd2,
A);
612 const APInt *ConstB, *ConstD;
620 APInt NewMask = *ConstB & *ConstD;
621 if (NewMask == *ConstB)
623 if (NewMask == *ConstD) {
626 RHSI->dropPoisonGeneratingFlags();
637 APInt NewMask = *ConstB | *ConstD;
638 if (NewMask == *ConstB)
640 if (NewMask == *ConstD)
667 const APInt *OldConstC, *OldConstE;
673 const APInt ConstC = PredL != CC ? *ConstB ^ *OldConstC : *OldConstC;
674 const APInt ConstE = PredR != CC ? *ConstD ^ *OldConstE : *OldConstE;
676 if (((*ConstB & *ConstD) & (ConstC ^ ConstE)).getBoolValue())
677 return IsNot ? nullptr : ConstantInt::get(
LHS->getType(), !IsAnd);
680 !ConstD->isSubsetOf(*ConstB))
685 BD = *ConstB & *ConstD;
686 CE = ConstC & ConstE;
688 BD = *ConstB | *ConstD;
689 CE = ConstC | ConstE;
691 Value *NewAnd = Builder.CreateAnd(
A, BD);
692 Value *CEVal = ConstantInt::get(
A->getType(), CE);
693 return Builder.CreateICmp(CC, NewAnd, CEVal);
697 return FoldBMixed(NewCC,
false);
699 return FoldBMixed(NewCC,
true);
714 D = Builder.CreateFreeze(
D);
715 Value *Mask = Builder.CreateOr(
B,
D);
717 return Builder.CreateICmp(NewCC,
Masked, Mask);
776 if (!
Known.isNonNegative())
795 if (PredL != Pred || PredR != Pred)
818 if (!LHSOneUse || !RHSOneUse || !
match(LHS1,
m_Zero()) || RHS0 != LHS0 ||
822 Value *
And = Builder.CreateAnd(LHS0, RHS1);
823 return Builder.CreateICmp(Pred,
And, LHS0);
866 APInt &SignBitMask) ->
bool {
867 const APInt *I01, *I1;
881 if (tryToMatchSignedTruncationCheck(PredR, RHS0, RHS1, X1, HighestBit)) {
885 }
else if (!tryToMatchSignedTruncationCheck(PredL, LHS0, LHS1, X1,
889 assert(HighestBit.
isPowerOf2() &&
"expected to be power of two (non-zero)");
893 APInt &UnsetBitsMask) ->
bool {
901 UnsetBitsMask = Res->Mask;
911 if (!tryToDecompose(PredR, RHS0, RHS1, X0, UnsetBitsMask))
914 assert(!UnsetBitsMask.
isZero() &&
"empty mask makes no sense.");
929 APInt SignBitsMask = ~(HighestBit - 1U);
936 if (!UnsetBitsMask.
isSubsetOf(SignBitsMask)) {
937 APInt OtherHighestBit = (~UnsetBitsMask) + 1U;
945 return Builder.CreateICmpULT(
X, ConstantInt::get(
X->getType(), HighestBit),
946 CxtI.
getName() +
".simplified");
966 CtPop->dropPoisonGeneratingAnnotations();
968 return Builder.CreateICmpUGT(CtPop, ConstantInt::get(CtPop->getType(), 1));
972 CtPop->dropPoisonGeneratingAnnotations();
974 return Builder.CreateICmpULT(CtPop, ConstantInt::get(CtPop->getType(), 2));
1000 CtPop->dropPoisonGeneratingAnnotations();
1002 return Builder.CreateICmpEQ(CtPop, ConstantInt::get(CtPop->getType(), 1));
1010 CtPop->dropPoisonGeneratingAnnotations();
1012 return Builder.CreateICmpNE(CtPop, ConstantInt::get(CtPop->getType(), 1));
1026 "Expected equality predicates for masked type of icmps.");
1046 const APInt *BCst, *DCst, *ECst;
1060 if (!BFVTy || !BConst || !DConst || !EConst)
1063 for (
unsigned I = 0;
I != BFVTy->getNumElements(); ++
I) {
1064 const auto *BElt = BConst->getAggregateElement(
I);
1065 const auto *DElt = DConst->getAggregateElement(
I);
1066 const auto *EElt = EConst->getAggregateElement(
I);
1068 if (!BElt || !DElt || !EElt)
1070 if (!isReducible(BElt, DElt, EElt))
1075 if (!isReducible(
B,
D,
E))
1093 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *
E =
nullptr;
1098 std::optional<std::pair<unsigned, unsigned>> MaskPair =
1104 unsigned CmpMask0 = MaskPair->first;
1105 unsigned CmpMask1 = MaskPair->second;
1106 if ((CmpMask0 &
Mask_AllZeros) && (CmpMask1 == compareBMask)) {
1110 }
else if ((CmpMask0 == compareBMask) && (CmpMask1 &
Mask_AllZeros)) {
1121 Value *LHS1,
bool LHSOneUse,
1123 Value *RHS1,
bool RHSOneUse,
1132 else if (RHS1 == LHS0) {
1139 !(LHSOneUse || RHSOneUse))
1154 GetKnownNonZeroAndOther(
B,
A))
1155 return Builder.CreateICmpULT(Builder.CreateNeg(
B),
A);
1157 GetKnownNonZeroAndOther(
B,
A))
1158 return Builder.CreateICmpUGE(Builder.CreateNeg(
B),
A);
1173 return std::nullopt;
1175 unsigned NumOriginalBits =
X->getType()->getScalarSizeInBits();
1176 unsigned NumExtractedBits = V->getType()->getScalarSizeInBits();
1182 Shift->
ule(NumOriginalBits - NumExtractedBits))
1184 return {{
X, 0, NumExtractedBits}};
1191 V = Builder.CreateLShr(V,
P.StartBit);
1193 if (TruncTy != V->getType())
1194 V = Builder.CreateTrunc(V, TruncTy);
1201Value *InstCombinerImpl::foldEqOfParts(
Value *Cmp0,
Value *Cmp1,
bool IsAnd) {
1206 auto GetMatchPart = [&](
Value *CmpV,
1207 unsigned OpNo) -> std::optional<IntPart> {
1216 return {{OpNo == 0 ?
X :
Y, 0, 1}};
1220 return std::nullopt;
1222 if (Pred ==
Cmp->getPredicate())
1231 return std::nullopt;
1240 return std::nullopt;
1242 return std::nullopt;
1247 return {{
I->getOperand(OpNo), From,
C->getBitWidth() - From}};
1250 std::optional<IntPart> L0 = GetMatchPart(Cmp0, 0);
1251 std::optional<IntPart> R0 = GetMatchPart(Cmp0, 1);
1252 std::optional<IntPart> L1 = GetMatchPart(Cmp1, 0);
1253 std::optional<IntPart> R1 = GetMatchPart(Cmp1, 1);
1254 if (!L0 || !R0 || !L1 || !R1)
1259 if (L0->From != L1->From || R0->From != R1->From) {
1260 if (L0->From != R1->From || R0->From != L1->From)
1267 if (L0->StartBit + L0->NumBits != L1->StartBit ||
1268 R0->StartBit + R0->NumBits != R1->StartBit) {
1269 if (L1->StartBit + L1->NumBits != L0->StartBit ||
1270 R1->StartBit + R1->NumBits != R0->StartBit)
1277 IntPart
L = {L0->From, L0->StartBit, L0->NumBits + L1->NumBits};
1278 IntPart
R = {R0->From, R0->StartBit, R0->NumBits + R1->NumBits};
1290 Value *RHS1,
bool RHSOneUse,
bool IsAnd,
1310 }
else if (LHS0 == RHS1)
1321 if (!SubstituteCmp) {
1326 SubstituteCmp = Builder.CreateICmp(PredR,
Y, LHS1);
1330 return IsAnd ? Builder.CreateLogicalAnd(
LHS, SubstituteCmp,
"", MDFrom)
1331 : Builder.CreateLogicalOr(
LHS, SubstituteCmp,
"", MDFrom);
1333 return Builder.CreateBinOp(IsAnd ? Instruction::And : Instruction::Or,
LHS,
1341Value *InstCombinerImpl::foldAndOrOfICmpsUsingRanges(
1345 auto MatchExactRangeCheck =
1347 Value *
RHS) -> std::optional<std::pair<Value *, ConstantRange>> {
1350 return std::nullopt;
1357 C->countr_zero() >=
Mask->countr_zero()) {
1358 ConstantRange CR(*
C, *
C - *Mask);
1361 return std::make_pair(
X, CR);
1368 return std::make_pair(
X, CR.
subtract(*C1));
1369 return std::make_pair(
LHS, CR);
1372 auto RC1 = MatchExactRangeCheck(PredL, LHS0, LHS1);
1376 auto RC2 = MatchExactRangeCheck(PredR, RHS0, RHS1);
1380 auto &[
V1, CR1] = *RC1;
1381 auto &[V2, CR2] = *RC2;
1387 CR1 = CR1.inverse();
1388 CR2 = CR2.inverse();
1391 Type *Ty =
V1->getType();
1395 if (!LHSOneUse || !RHSOneUse || CR1.isWrappedSet() || CR2.isWrappedSet())
1400 APInt LowerDiff = CR1.getLower() ^ CR2.getLower();
1401 APInt UpperDiff = (CR1.getUpper() - 1) ^ (CR2.getUpper() - 1);
1402 APInt CR1Size = CR1.getUpper() - CR1.getLower();
1403 if (!LowerDiff.
isPowerOf2() || LowerDiff != UpperDiff ||
1404 CR1Size != CR2.getUpper() - CR2.getLower())
1407 CR = CR1.getLower().ult(CR2.getLower()) ? CR1 : CR2;
1408 NewV =
Builder.CreateAnd(NewV, ConstantInt::get(Ty, ~LowerDiff));
1416 CR->getEquivalentICmp(NewPred, NewC,
Offset);
1419 NewV =
Builder.CreateAdd(NewV, ConstantInt::get(Ty,
Offset));
1420 return Builder.CreateICmp(NewPred, NewV, ConstantInt::get(Ty, NewC));
1439 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1440 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1452 bool IsAnd,
bool IsLogicalSelect) {
1453 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1454 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1457 if (LHS0 == RHS1 && RHS0 == LHS1) {
1477 if (LHS0 == RHS0 && LHS1 == RHS1) {
1480 unsigned NewPred = IsAnd ? FCmpCodeL & FCmpCodeR : FCmpCodeL | FCmpCodeR;
1500 FastMathFlags FMF =
LHS->getFastMathFlags() &
RHS->getFastMathFlags();
1501 if (IsLogicalSelect) {
1502 Y =
Builder.CreateFreeze(
Y,
Y->getName() +
".fr");
1506 return Builder.CreateFCmpFMF(PredL, LHS0,
Y, FMF);
1511 if (!IsLogicalSelect && IsAnd &&
1527 auto [ClassValRHS, ClassMaskRHS] =
1530 auto [ClassValLHS, ClassMaskLHS] =
1532 if (ClassValLHS == ClassValRHS) {
1533 unsigned CombinedMask = IsAnd ? (ClassMaskLHS & ClassMaskRHS)
1534 : (ClassMaskLHS | ClassMaskRHS);
1535 return Builder.CreateIntrinsic(
1536 Intrinsic::is_fpclass, {ClassValLHS->getType()},
1537 {ClassValLHS,
Builder.getInt32(CombinedMask)});
1565 if (IsLessThanOrLessEqual(IsAnd ? PredR : PredL)) {
1569 if (IsLessThanOrLessEqual(IsAnd ? PredL : PredR)) {
1570 FastMathFlags NewFlag =
LHS->getFastMathFlags();
1571 if (!IsLogicalSelect)
1572 NewFlag |=
RHS->getFastMathFlags();
1576 PredL, FAbs, ConstantFP::get(LHS0->
getType(), *LHSC), NewFlag);
1588 if (!FCmp || !FCmp->hasOneUse())
1591 std::tie(ClassVal, ClassMask) =
1592 fcmpToClassTest(FCmp->getPredicate(), *FCmp->getParent()->getParent(),
1593 FCmp->getOperand(0), FCmp->getOperand(1));
1594 return ClassVal !=
nullptr;
1605 Value *ClassVal0 =
nullptr;
1606 Value *ClassVal1 =
nullptr;
1623 ClassVal0 == ClassVal1) {
1624 unsigned NewClassMask;
1626 case Instruction::And:
1627 NewClassMask = ClassMask0 & ClassMask1;
1629 case Instruction::Or:
1630 NewClassMask = ClassMask0 | ClassMask1;
1632 case Instruction::Xor:
1633 NewClassMask = ClassMask0 ^ ClassMask1;
1642 1, ConstantInt::get(
II->getArgOperand(1)->getType(), NewClassMask));
1649 1, ConstantInt::get(
II->getArgOperand(1)->getType(), NewClassMask));
1654 Builder.CreateIntrinsic(Intrinsic::is_fpclass, {ClassVal0->
getType()},
1655 {ClassVal0,
Builder.getInt32(NewClassMask)});
1669Instruction *InstCombinerImpl::canonicalizeConditionalNegationViaMathToSelect(
1671 assert(
I.getOpcode() == BinaryOperator::Xor &&
"Only for xor!");
1676 !
Cond->getType()->isIntOrIntVectorTy(1) ||
1679 return createSelectInstWithUnknownProfile(
1690 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1691 "Expecting and/or op for fcmp transform");
1710 X->getType() !=
Y->getType())
1714 X->getType() !=
Y->getType())
1731 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1732 "Trying to match De Morgan's Laws with something other than and/or");
1736 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1738 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1764bool InstCombinerImpl::shouldOptimizeCast(
CastInst *CI) {
1774 if (isEliminableCastPair(PrecedingCI, CI))
1802 auto *ZExt =
new ZExtInst(NewOp, DestTy);
1803 ZExt->setNonNeg(Flags.NNeg);
1804 ZExt->andIRFlags(Cast);
1813 return new SExtInst(NewOp, DestTy);
1823 assert(
I.isBitwiseLogicOp() &&
"Unexpected opcode for bitwise logic folding");
1825 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1831 auto FoldBitwiseICmpZeroWithICmp = [&](
Value *Op0,
1832 Value *Op1) -> Instruction * {
1847 auto *BitwiseOp =
Builder.CreateBinOp(LogicOpc, ICmpL, ICmpR);
1849 return new ZExtInst(BitwiseOp, Op0->
getType());
1852 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op0, Op1))
1855 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op1, Op0))
1864 Type *DestTy =
I.getType();
1890 unsigned XNumBits =
X->getType()->getScalarSizeInBits();
1891 unsigned YNumBits =
Y->getType()->getScalarSizeInBits();
1892 if (XNumBits != YNumBits) {
1900 if (XNumBits < YNumBits) {
1901 X =
Builder.CreateCast(CastOpcode,
X,
Y->getType());
1902 }
else if (YNumBits < XNumBits) {
1903 Y =
Builder.CreateCast(CastOpcode,
Y,
X->getType());
1908 Value *NarrowLogic =
Builder.CreateBinOp(LogicOpc,
X,
Y,
I.getName());
1911 if (Disjoint && NewDisjoint)
1912 NewDisjoint->setIsDisjoint(Disjoint->isDisjoint());
1924 if (shouldOptimizeCast(Cast0) && shouldOptimizeCast(Cast1)) {
1925 Value *NewOp =
Builder.CreateBinOp(LogicOpc, Cast0Src, Cast1Src,
1931 NewTrunc->setHasNoUnsignedWrap(
1932 LogicOpc == Instruction::And
1933 ? Trunc0->hasNoUnsignedWrap() || Trunc1->hasNoUnsignedWrap()
1934 : Trunc0->hasNoUnsignedWrap() && Trunc1->hasNoUnsignedWrap());
1935 NewTrunc->setHasNoSignedWrap(Trunc0->hasNoSignedWrap() &&
1936 Trunc1->hasNoSignedWrap());
1946 assert(
I.getOpcode() == Instruction::And);
1947 Value *Op0 =
I.getOperand(0);
1948 Value *Op1 =
I.getOperand(1);
1956 return BinaryOperator::CreateXor(
A,
B);
1972 assert(
I.getOpcode() == Instruction::Or);
1973 Value *Op0 =
I.getOperand(0);
1974 Value *Op1 =
I.getOperand(1);
1999 return BinaryOperator::CreateXor(
A,
B);
2019 Value *Op0 =
And.getOperand(0), *Op1 =
And.getOperand(1);
2040 if (
Opc == Instruction::LShr ||
Opc == Instruction::Shl)
2049 return new ZExtInst(
Builder.CreateAnd(NewBO,
X), Ty);
2057 assert(Opcode == Instruction::And || Opcode == Instruction::Or);
2061 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
2063 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2070 const auto matchNotOrAnd =
2071 [Opcode, FlippedOpcode](
Value *
Op,
auto m_A,
auto m_B,
auto m_C,
2072 Value *&
X,
bool CountUses =
false) ->
bool {
2073 if (CountUses && !
Op->hasOneUse())
2079 return !CountUses ||
X->hasOneUse();
2095 return (Opcode == Instruction::Or)
2096 ? BinaryOperator::CreateAnd(
Xor, Builder.CreateNot(
A))
2105 return (Opcode == Instruction::Or)
2106 ? BinaryOperator::CreateAnd(
Xor, Builder.CreateNot(
B))
2115 Opcode, Builder.CreateBinOp(FlippedOpcode,
B,
C),
A));
2122 Opcode, Builder.CreateBinOp(FlippedOpcode,
A,
C),
B));
2128 if (Opcode == Instruction::Or && Op0->
hasOneUse() &&
2166 return (Opcode == Instruction::Or)
2168 : BinaryOperator::CreateOr(
Xor,
X);
2176 FlippedOpcode, Builder.CreateBinOp(Opcode,
C, Builder.CreateNot(
B)),
2184 FlippedOpcode, Builder.CreateBinOp(Opcode,
B, Builder.CreateNot(
C)),
2204 if (!
X->hasOneUse()) {
2205 Value *YZ = Builder.CreateBinOp(Opcode,
Y, Z);
2209 if (!
Y->hasOneUse()) {
2210 Value *XZ = Builder.CreateBinOp(Opcode,
X, Z);
2230 Type *Ty =
I.getType();
2232 Value *Op0 =
I.getOperand(0);
2233 Value *Op1 =
I.getOperand(1);
2241 unsigned Width = Ty->getScalarSizeInBits();
2245 case Instruction::And:
2246 if (
C->countl_one() < LastOneMath)
2249 case Instruction::Xor:
2250 case Instruction::Or:
2251 if (
C->countl_zero() < LastOneMath)
2258 Value *NewBinOp = Builder.CreateBinOp(OpC,
X, ConstantInt::get(Ty, *
C));
2260 ConstantInt::get(Ty, *C2), Op0);
2267 assert((
I.isBitwiseLogicOp() ||
I.getOpcode() == Instruction::Add) &&
2268 "Unexpected opcode");
2271 Constant *ShiftedC1, *ShiftedC2, *AddC;
2272 Type *Ty =
I.getType();
2288 if (!Op0Inst || !Op1Inst)
2294 if (ShiftOp != Op1Inst->getOpcode())
2298 if (
I.getOpcode() == Instruction::Add && ShiftOp != Instruction::Shl)
2302 I.getOpcode(), ShiftedC1,
Builder.CreateBinOp(ShiftOp, ShiftedC2, AddC));
2318 assert(
I.isBitwiseLogicOp() &&
"Should and/or/xor");
2319 if (!
I.getOperand(0)->hasOneUse())
2326 if (
Y && (!
Y->hasOneUse() ||
X->getIntrinsicID() !=
Y->getIntrinsicID()))
2332 if (!
Y && (!(IID == Intrinsic::bswap || IID == Intrinsic::bitreverse) ||
2337 case Intrinsic::fshl:
2338 case Intrinsic::fshr: {
2339 if (
X->getOperand(2) !=
Y->getOperand(2))
2342 Builder.CreateBinOp(
I.getOpcode(),
X->getOperand(0),
Y->getOperand(0));
2344 Builder.CreateBinOp(
I.getOpcode(),
X->getOperand(1),
Y->getOperand(1));
2349 case Intrinsic::bswap:
2350 case Intrinsic::bitreverse: {
2351 Value *NewOp0 = Builder.CreateBinOp(
2352 I.getOpcode(),
X->getOperand(0),
2353 Y ?
Y->getOperand(0)
2354 : ConstantInt::get(
I.getType(), IID == Intrinsic::bswap
2374 unsigned Depth = 0) {
2382 if (!
I || !
I->isBitwiseLogicOp() ||
Depth >= 3)
2385 if (!
I->hasOneUse())
2386 SimplifyOnly =
true;
2389 SimplifyOnly, IC,
Depth + 1);
2391 SimplifyOnly, IC,
Depth + 1);
2392 if (!NewOp0 && !NewOp1)
2396 NewOp0 =
I->getOperand(0);
2398 NewOp1 =
I->getOperand(1);
2421 APInt Mask = ~*NegP;
2437 Type *Ty =
I.getType();
2438 Value *NewAdd = Builder.CreateAdd(
X, ConstantInt::get(Ty, Mask));
2439 return BinaryOperator::CreateAnd(NewAdd, ConstantInt::get(Ty, *NegP));
2447 bool RHSIsLogical) {
2449 Value *Folded =
nullptr;
2452 if (
Value *Res = foldBooleanAndOr(
LHS,
X,
I, IsAnd,
false))
2453 Folded = RHSIsLogical ?
Builder.CreateLogicalOp(Opcode, Res,
Y)
2454 :
Builder.CreateBinOp(Opcode, Res,
Y);
2457 else if (
Value *Res = foldBooleanAndOr(
LHS,
Y,
I, IsAnd,
false))
2458 Folded = RHSIsLogical ?
Builder.CreateLogicalOp(Opcode,
X, Res)
2459 :
Builder.CreateBinOp(Opcode,
X, Res);
2476 Type *Ty =
I.getType();
2479 SQ.getWithInstruction(&
I)))
2510 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2519 Value *IsZero =
Builder.CreateICmpEQ(
X, ConstantInt::get(Ty, 0));
2529 return createSelectInstWithUnknownProfile(Cmp,
2539 return BinaryOperator::CreateAnd(
Builder.CreateNot(
X),
Y);
2545 Constant *NewC = ConstantInt::get(Ty, *
C & *XorC);
2548 return BinaryOperator::CreateXor(
And, NewC);
2559 APInt Together = *
C & *OrC;
2562 return BinaryOperator::CreateOr(
And, ConstantInt::get(Ty, Together));
2565 unsigned Width = Ty->getScalarSizeInBits();
2566 const APInt *ShiftC;
2568 ShiftC->
ult(Width)) {
2573 Constant *ShAmtC = ConstantInt::get(Ty, ShiftC->
zext(Width));
2574 return BinaryOperator::CreateLShr(Sext, ShAmtC);
2582 return BinaryOperator::CreateLShr(
X, ConstantInt::get(Ty, *ShiftC));
2590 if (Op0->
hasOneUse() &&
C->isPowerOf2() && (*AddC & (*
C - 1)) == 0) {
2591 assert((*
C & *AddC) != 0 &&
"Expected common bit");
2593 return BinaryOperator::CreateXor(NewAnd, Op1);
2600 switch (
B->getOpcode()) {
2601 case Instruction::Xor:
2602 case Instruction::Or:
2603 case Instruction::Mul:
2604 case Instruction::Add:
2605 case Instruction::Sub:
2621 C->isIntN(
X->getType()->getScalarSizeInBits())) {
2622 unsigned XWidth =
X->getType()->getScalarSizeInBits();
2623 Constant *TruncC1 = ConstantInt::get(
X->getType(), C1->
trunc(XWidth));
2625 ?
Builder.CreateBinOp(BOpcode,
X, TruncC1)
2626 :
Builder.CreateBinOp(BOpcode, TruncC1,
X);
2627 Constant *TruncC = ConstantInt::get(
X->getType(),
C->trunc(XWidth));
2637 C->isMask(
X->getType()->getScalarSizeInBits())) {
2639 Value *TrY =
Builder.CreateTrunc(
Y,
X->getType(),
Y->getName() +
".tr");
2647 C->isMask(
X->getType()->getScalarSizeInBits())) {
2649 Value *TrY =
Builder.CreateTrunc(
Y,
X->getType(),
Y->getName() +
".tr");
2666 Value *NewRHS =
Builder.CreateAnd(
Y, Op1,
Y->getName() +
".masked");
2672 Value *NewLHS =
Builder.CreateAnd(
X, Op1,
X->getName() +
".masked");
2681 if (
C->isPowerOf2() &&
2684 int Log2C =
C->exactLogBase2();
2687 int BitNum = IsShiftLeft ? Log2C - Log2ShiftC : Log2ShiftC - Log2C;
2688 assert(BitNum >= 0 &&
"Expected demanded bits to handle impossible mask");
2689 Value *Cmp =
Builder.CreateICmpEQ(
X, ConstantInt::get(Ty, BitNum));
2690 return createSelectInstWithUnknownProfile(Cmp, ConstantInt::get(Ty, *
C),
2710 return createSelectInstWithUnknownProfile(
2721 if (Cmp && Cmp->isNullValue()) {
2727 return createSelectInstWithUnknownProfile(
2745 !
Builder.GetInsertBlock()->getParent()->hasFnAttribute(
2746 Attribute::NoImplicitFloat)) {
2761 APInt(Ty->getScalarSizeInBits(),
2762 Ty->getScalarSizeInBits() -
2763 X->getType()->getScalarSizeInBits())))) {
2764 auto *SExt =
Builder.CreateSExt(
X, Ty,
X->getName() +
".signext");
2765 return BinaryOperator::CreateAnd(SExt, Op1);
2771 if (
I.getType()->isIntOrIntVectorTy(1)) {
2774 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
true))
2779 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
true))
2794 return BinaryOperator::CreateAnd(Op0,
B);
2797 return BinaryOperator::CreateAnd(Op1,
B);
2805 if (NotC !=
nullptr)
2806 return BinaryOperator::CreateAnd(Op0, NotC);
2815 if (NotC !=
nullptr)
2816 return BinaryOperator::CreateAnd(Op1, NotC);
2825 return BinaryOperator::CreateAnd(
A,
B);
2833 return BinaryOperator::CreateAnd(
A,
B);
2841 return BinaryOperator::CreateAnd(
Builder.CreateNot(
A),
B);
2849 return BinaryOperator::CreateAnd(
Builder.CreateNot(
A),
B);
2853 foldBooleanAndOr(Op0, Op1,
I,
true,
false))
2858 if (
auto *V = reassociateBooleanAndOr(Op0,
X,
Y,
I,
true,
2864 if (
auto *V = reassociateBooleanAndOr(Op1,
X,
Y,
I,
true,
2872 if (
Instruction *CastedAnd = foldCastedBitwiseLogic(
I))
2885 A->getType()->isIntOrIntVectorTy(1))
2891 A->getType()->isIntOrIntVectorTy(1))
2896 A->getType()->isIntOrIntVectorTy(1))
2897 return createSelectInstWithUnknownProfile(
2898 A,
Builder.CreateAnd(
B, ConstantInt::get(Ty, 1)),
2904 if (
A->getType()->isIntOrIntVectorTy(1))
2908 return createSelectInstWithUnknownProfile(
2918 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2920 return createSelectInstWithUnknownProfile(IsNeg,
Y,
2928 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2930 return createSelectInstWithUnknownProfile(IsNeg,
2940 Value *Start =
nullptr, *Step =
nullptr;
2948 return Canonicalized;
2950 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
2962 return BinaryOperator::CreateAnd(V, Op1);
2966 return BinaryOperator::CreateAnd(Op0, V);
2976 bool MatchBitReversals) {
2984 for (
auto *Inst : Insts) {
2985 Inst->setDebugLoc(
I.getDebugLoc());
2991std::optional<std::pair<Intrinsic::ID, SmallVector<Value *, 3>>>
2995 assert(
Or.getOpcode() == BinaryOperator::Or &&
"Expecting or instruction");
2997 unsigned Width =
Or.getType()->getScalarSizeInBits();
3002 return std::nullopt;
3010 Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
3016 return std::nullopt;
3019 if (Or0->
getOpcode() == BinaryOperator::LShr) {
3025 Or1->
getOpcode() == BinaryOperator::LShr &&
3026 "Illegal or(shift,shift) pair");
3030 auto matchShiftAmount = [&](
Value *L,
Value *R,
unsigned Width) ->
Value * {
3032 const APInt *LI, *RI;
3034 if (LI->
ult(Width) && RI->
ult(Width) && (*LI + *RI) == Width)
3035 return ConstantInt::get(L->getType(), *LI);
3059 if (ShVal0 != ShVal1)
3070 unsigned Mask = Width - 1;
3078 Value *XPlusOne =
nullptr;
3105 Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, Width);
3107 ShAmt = matchShiftAmount(ShAmt1, ShAmt0, Width);
3111 return std::nullopt;
3113 FShiftArgs = {ShVal0, ShVal1, ShAmt};
3130 const APInt *ZextHighShlAmt;
3133 return std::nullopt;
3137 return std::nullopt;
3139 unsigned HighSize =
High->getType()->getScalarSizeInBits();
3140 unsigned LowSize =
Low->getType()->getScalarSizeInBits();
3143 if (ZextHighShlAmt->
ult(LowSize) || ZextHighShlAmt->
ugt(Width - HighSize))
3144 return std::nullopt;
3154 const APInt *ZextLowShlAmt;
3161 if (*ZextLowShlAmt + *ZextHighShlAmt != Width)
3167 ZextLowShlAmt->
ule(Width - LowSize) &&
"Invalid concat");
3176 FShiftArgs = {U, U, ConstantInt::get(Or0->
getType(), *ZextHighShlAmt)};
3181 if (FShiftArgs.
empty())
3182 return std::nullopt;
3184 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
3185 return std::make_pair(IID, FShiftArgs);
3191 auto [IID, FShiftArgs] = *Opt;
3202 assert(
Or.getOpcode() == Instruction::Or &&
"bswap requires an 'or'");
3203 Value *Op0 =
Or.getOperand(0), *Op1 =
Or.getOperand(1);
3206 unsigned Width = Ty->getScalarSizeInBits();
3207 if ((Width & 1) != 0)
3209 unsigned HalfWidth = Width / 2;
3216 Value *LowerSrc, *ShlVal, *UpperSrc;
3227 Value *NewLower = Builder.CreateZExt(
Lo, Ty);
3228 Value *NewUpper = Builder.CreateZExt(
Hi, Ty);
3229 NewUpper = Builder.CreateShl(NewUpper, HalfWidth);
3230 Value *BinOp = Builder.CreateDisjointOr(NewLower, NewUpper);
3231 return Builder.CreateIntrinsic(
id, Ty, BinOp);
3236 Value *LowerBSwap, *UpperBSwap;
3239 return ConcatIntrinsicCalls(Intrinsic::bswap, UpperBSwap, LowerBSwap);
3243 Value *LowerBRev, *UpperBRev;
3246 return ConcatIntrinsicCalls(Intrinsic::bitreverse, UpperBRev, LowerBRev);
3258 return Builder.CreateSExt(
X, Ty);
3266 for (
unsigned i = 0; i != NumElts; ++i) {
3269 if (!EltC1 || !EltC2)
3288 Type *Ty =
A->getType();
3304 if (
A->getType()->isIntOrIntVectorTy()) {
3306 if (NumSignBits ==
A->getType()->getScalarSizeInBits() &&
3329 Cond->getType()->isIntOrIntVectorTy(1)) {
3355 Cond->getType()->isIntOrIntVectorTy(1) &&
3369 Value *
D,
bool InvertFalseVal) {
3375 if (
Value *
Cond = getSelectCondition(
A,
C, InvertFalseVal)) {
3380 Type *SelTy =
A->getType();
3383 unsigned Elts = VecTy->getElementCount().getKnownMinValue();
3387 Type *EltTy =
Builder.getIntNTy(SelEltSize / Elts);
3404 Value *LHS1,
bool LHSOneUse,
3406 Value *RHS1,
bool RHSOneUse,
3407 bool IsAnd,
bool IsLogical,
3419 auto MatchRHSOp = [LHS0, CInt](
const Value *RHSOp) {
3422 (CInt->
isZero() && RHSOp == LHS0);
3436 return Builder.CreateICmp(
3438 Builder.CreateSub(LHS0, ConstantInt::get(LHS0->
getType(), *CInt + 1)),
3448 CmpPredicate PredL, PredR;
3449 Value *LHS0, *LHS1, *RHS0, *RHS1;
3457 const SimplifyQuery Q =
SQ.getWithInstruction(&
I);
3459 const APInt *LHSC =
nullptr, *RHSC =
nullptr;
3466 if (LHS0 == RHS1 && LHS1 == RHS0) {
3470 if (LHS0 == RHS0 && LHS1 == RHS1) {
3479 PredR, RHS0, RHS1, RHSOneUse,
3485 PredR, RHS0, RHS1, RHSOneUse, PredL, LHS0, LHS1, LHSOneUse, IsAnd,
3490 RHS0, RHS1, RHSOneUse, IsAnd,
3499 PredR, RHS0, RHS1,
RHS, PredL, LHS0, LHS1, LHSOneUse, IsAnd,
3504 CmpR->setSameSign(
false);
3534 if (IsAnd && !IsLogical)
3549 PredR, RHS0, RHS1, RHSOneUse,
3553 PredL, LHS0, LHS1, LHSOneUse,
3567 return Builder.CreateICmp(PredL, NewOr,
3579 return Builder.CreateICmp(PredL, NewAnd,
3585 Builder, PredL, LHS0, LHS1, LHSOneUse, PredR, RHS0, RHS1, RHSOneUse,
3600 const APInt *AndC, *SmallC =
nullptr, *BigC =
nullptr;
3614 if (SmallC && BigC) {
3615 unsigned BigBitSize = BigC->getBitWidth();
3622 APInt
N = SmallC->
zext(BigBitSize) | *BigC;
3624 return Builder.CreateICmp(PredL, NewAnd, NewVal);
3634 bool TrueIfSignedL, TrueIfSignedR;
3640 if ((TrueIfSignedL && !TrueIfSignedR &&
3643 (!TrueIfSignedL && TrueIfSignedR &&
3647 return Builder.CreateIsNeg(NewXor);
3650 if ((TrueIfSignedL && !TrueIfSignedR &&
3653 (!TrueIfSignedL && TrueIfSignedR &&
3657 return Builder.CreateIsNotNeg(NewXor);
3668 !
I.getFunction()->hasFnAttribute(Attribute::NoImplicitFloat) &&
3669 LHSOneUse && RHSOneUse &&
3671 X->getType()->getScalarType()->isIEEELikeFPTy() &&
3672 APFloat(
X->getType()->getScalarType()->getFltSemantics(), *MaskC)
3674 ((LHSC->
isZero() && *RHSC == *MaskC) ||
3675 (RHSC->
isZero() && *LHSC == *MaskC)))
3679 return foldAndOrOfICmpsUsingRanges(PredL, LHS0, LHS1, LHSOneUse, PredR, RHS0,
3680 RHS1, RHSOneUse, IsAnd);
3695 SQ.getWithInstruction(&
I)))
3698 if (
Value *Res = foldAndOrOfICmps(
LHS,
RHS,
I, IsAnd, IsLogical))
3703 if (
Value *Res = foldLogicOfFCmps(LHSCmp, RHSCmp, IsAnd, IsLogical))
3714 assert(
I.getOpcode() == Instruction::Or &&
3715 "Simplification only supports or at the moment.");
3717 Value *Cmp1, *Cmp2, *Cmp3, *Cmp4;
3724 return Builder.CreateXor(Cmp1, Cmp4);
3726 return Builder.CreateXor(Cmp1, Cmp3);
3756 const unsigned EltBitWidth = EltTy->getBitWidth();
3758 if (TargetBitWidth % EltBitWidth != 0 || ShlAmt % EltBitWidth != 0)
3760 const unsigned TargetEltWidth = TargetBitWidth / EltBitWidth;
3761 const unsigned ShlEltAmt = ShlAmt / EltBitWidth;
3763 const unsigned MaskIdx =
3764 DL.isLittleEndian() ? ShlEltAmt : TargetEltWidth - ShlEltAmt - 1;
3766 VecOffset =
static_cast<int64_t
>(VecIdx) -
static_cast<int64_t
>(MaskIdx);
3767 Mask.resize(TargetEltWidth);
3781 Mask.resize(SrcTy->getNumElements());
3795 const unsigned NumVecElts = VecTy->getNumElements();
3796 bool FoundVecOffset =
false;
3797 for (
unsigned Idx = 0; Idx < ShuffleMask.size(); ++Idx) {
3800 const unsigned ShuffleIdx = ShuffleMask[Idx];
3801 if (ShuffleIdx >= NumVecElts) {
3802 const unsigned ConstIdx = ShuffleIdx - NumVecElts;
3805 if (!ConstElt || !ConstElt->isNullValue())
3810 if (FoundVecOffset) {
3811 if (VecOffset + Idx != ShuffleIdx)
3814 if (ShuffleIdx < Idx)
3816 VecOffset = ShuffleIdx - Idx;
3817 FoundVecOffset =
true;
3821 return FoundVecOffset;
3834 bool AlreadyInsertedMaskedElt = Mask.test(InsertIdx);
3836 if (!AlreadyInsertedMaskedElt)
3837 Mask.reset(InsertIdx);
3846 assert(
I.getOpcode() == Instruction::Or);
3847 Value *LhsVec, *RhsVec;
3848 int64_t LhsVecOffset, RhsVecOffset;
3856 if (LhsVec != RhsVec || LhsVecOffset != RhsVecOffset)
3860 const unsigned ZeroVecIdx =
3863 for (
unsigned Idx : Mask.set_bits()) {
3864 assert(LhsVecOffset + Idx >= 0);
3865 ShuffleMask[Idx] = LhsVecOffset + Idx;
3868 Value *MaskedVec = Builder.CreateShuffleVector(
3870 I.getName() +
".v");
3896 const APInt *ShiftedMaskConst =
nullptr;
3903 if (!
match(MaskedOp0,
3908 if (LShrAmt > ShlAmt)
3910 Offset = ShlAmt - LShrAmt;
3912 Mask = ShiftedMaskConst ? ShiftedMaskConst->
shl(LShrAmt)
3914 Int->getType()->getScalarSizeInBits(), LShrAmt);
3924 Value *LhsInt, *RhsInt;
3925 APInt LhsMask, RhsMask;
3927 bool IsLhsShlNUW, IsLhsShlNSW, IsRhsShlNUW, IsRhsShlNSW;
3934 if (LhsInt != RhsInt || LhsOffset != RhsOffset)
3937 APInt Mask = LhsMask | RhsMask;
3940 Value *Res = Builder.CreateShl(
3942 Builder.CreateAnd(LhsInt, Mask, LhsInt->
getName() +
".mask"), DestTy,
3944 ConstantInt::get(DestTy, LhsOffset),
"", IsLhsShlNUW && IsRhsShlNUW,
3945 IsLhsShlNSW && IsRhsShlNSW);
3970 return std::nullopt;
3973 Value *Original =
nullptr;
3974 const APInt *Mask =
nullptr;
3975 const APInt *MulConst =
nullptr;
3978 if (MulConst->
isZero() || Mask->isZero())
3979 return std::nullopt;
3981 return std::optional<DecomposedBitMaskMul>(
3982 {Original, *MulConst, *Mask,
3988 const APInt *EqZero =
nullptr, *NeZero =
nullptr;
3992 auto ICmpDecompose =
3995 if (!ICmpDecompose.has_value())
3996 return std::nullopt;
4000 if (ICmpDecompose->X->getType() != V->getType())
4001 return std::nullopt;
4004 ICmpDecompose->C.isZero());
4009 if (!EqZero->
isZero() || NeZero->isZero())
4010 return std::nullopt;
4012 if (!ICmpDecompose->Mask.isPowerOf2() || ICmpDecompose->Mask.isZero())
4013 return std::nullopt;
4015 if (!NeZero->urem(ICmpDecompose->Mask).isZero())
4016 return std::nullopt;
4018 return std::optional<DecomposedBitMaskMul>(
4019 {ICmpDecompose->X, NeZero->udiv(ICmpDecompose->Mask),
4020 ICmpDecompose->Mask,
false,
false});
4023 return std::nullopt;
4039 if (Decomp0->isCombineableWith(*Decomp1)) {
4040 Value *NewAnd = Builder.CreateAnd(
4042 ConstantInt::get(Decomp0->X->getType(), Decomp0->Mask + Decomp1->Mask));
4044 return Builder.CreateMul(
4045 NewAnd, ConstantInt::get(NewAnd->
getType(), Decomp1->Factor),
"",
4046 Decomp0->NUW && Decomp1->NUW, Decomp0->NSW && Decomp1->NSW);
4065 if (
Value *Res = foldDisjointOr(
LHS,
X))
4066 return Builder.CreateDisjointOr(Res,
Y);
4067 if (
Value *Res = foldDisjointOr(
LHS,
Y))
4068 return Builder.CreateDisjointOr(Res,
X);
4072 if (
Value *Res = foldDisjointOr(
X,
RHS))
4073 return Builder.CreateDisjointOr(Res,
Y);
4074 if (
Value *Res = foldDisjointOr(
Y,
RHS))
4075 return Builder.CreateDisjointOr(Res,
X);
4089 const APInt *C1, *C2;
4098 Constant *NewC = ConstantInt::get(
X->getType(), C2->
udiv(*C1));
4119 return Builder.CreateBinaryIntrinsic(Intrinsic::abs,
X,
4120 Builder.getFalse());
4138 bool MayNeedFreeze = SelOp0 && SelOp1 &&
4139 match(SelOp1->getTrueValue(),
4144 Value *C2 =
nullptr, *A2 =
nullptr, *B2 =
nullptr;
4153 return createSelectInstWithUnknownProfile(
C,
A,
B);
4169 bool MayNeedFreeze = SelOp0 && SelOp1 &&
4170 match(SelOp0->getTrueValue(),
4175 Value *C2 =
nullptr, *A2 =
nullptr, *B2 =
nullptr;
4184 return createSelectInstWithUnknownProfile(
C,
B,
A);
4198 SQ.getWithInstruction(&
I)))
4234 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
4235 Type *Ty =
I.getType();
4236 if (Ty->isIntOrIntVectorTy(1)) {
4239 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
false))
4244 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
false))
4281 if (
Value *Res = foldDisjointOr(
I.getOperand(0),
I.getOperand(1)))
4284 if (
Value *Res = reassociateDisjointOr(
I.getOperand(0),
I.getOperand(1)))
4295 return BinaryOperator::CreateXor(
Or, ConstantInt::get(Ty, *CV));
4302 Value *IncrementY =
Builder.CreateAdd(
Y, ConstantInt::get(Ty, 1));
4303 return BinaryOperator::CreateMul(
X, IncrementY);
4320 if (
I.getType()->isIntOrIntVectorTy(1) &&
4333 const APInt *C0, *C1;
4339 return BinaryOperator::CreateOr(
Builder.CreateAnd(
X, *C0),
B);
4342 return BinaryOperator::CreateOr(
Builder.CreateAnd(
X, *C1),
A);
4346 return BinaryOperator::CreateXor(
Builder.CreateAnd(
X, *C0),
B);
4349 return BinaryOperator::CreateXor(
Builder.CreateAnd(
X, *C1),
A);
4352 if ((*C0 & *C1).
isZero()) {
4357 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
4358 return BinaryOperator::CreateAnd(
A, C01);
4364 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
4365 return BinaryOperator::CreateAnd(
B, C01);
4369 const APInt *C2, *C3;
4374 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
4375 return BinaryOperator::CreateAnd(
Or, C01);
4382 const APInt *ShiftAmt;
4385 ShiftAmt->
ult(
A->getType()->getScalarSizeInBits()) &&
4386 C1->isIntN(
A->getType()->getScalarSizeInBits() -
4388 return BinaryOperator::CreateAnd(
4389 A, ConstantInt::get(
I.getType(), *C0 | *C1));
4395 ShiftAmt->
ult(
A->getType()->getScalarSizeInBits()) &&
4396 C0->
isIntN(
A->getType()->getScalarSizeInBits() -
4398 return BinaryOperator::CreateAnd(
4399 B, ConstantInt::get(
I.getType(), *C0 | *C1));
4408 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D))
4410 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B))
4412 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D))
4414 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B))
4416 if (
Value *V = matchSelectFromAndOr(
B,
D,
A,
C))
4418 if (
Value *V = matchSelectFromAndOr(
B,
D,
C,
A))
4420 if (
Value *V = matchSelectFromAndOr(
D,
B,
A,
C))
4422 if (
Value *V = matchSelectFromAndOr(
D,
B,
C,
A))
4431 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D,
true))
4433 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B,
true))
4435 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D,
true))
4437 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B,
true))
4446 return BinaryOperator::CreateOr(Op0,
C);
4453 return BinaryOperator::CreateOr(Op1,
C);
4459 bool SwappedForXor =
false;
4462 SwappedForXor =
true;
4469 return BinaryOperator::CreateOr(Op0,
B);
4471 return BinaryOperator::CreateOr(Op0,
A);
4476 return BinaryOperator::CreateOr(
A,
B);
4504 return BinaryOperator::CreateOr(Nand,
C);
4512 foldBooleanAndOr(Op0, Op1,
I,
false,
false))
4517 if (
auto *V = reassociateBooleanAndOr(Op0,
X,
Y,
I,
false,
4523 if (
auto *V = reassociateBooleanAndOr(Op1,
X,
Y,
I,
false,
4543 A->getType()->isIntOrIntVectorTy(1))
4544 return createSelectInstWithUnknownProfile(
4563 Value *Inner =
Builder.CreateOr(
A, Op1,
"", IsDisjointOuter);
4565 return IsDisjointOuter && IsDisjointInner
4566 ? BinaryOperator::CreateDisjointOr(Inner, CI)
4567 : BinaryOperator::CreateOr(Inner, CI);
4574 Value *
X =
nullptr, *
Y =
nullptr;
4593 return createSelectInstWithUnknownProfile(NewICmpInst,
AllOnes,
X);
4606 return BinaryOperator::CreateXor(
A,
B);
4622 Value *
Mul, *Ov, *MulIsNotZero, *UMulWithOv;
4640 return BinaryOperator::CreateAnd(NotNullA, NotNullB);
4649 const APInt *C1, *C2;
4664 : C2->
uadd_ov(*C1, Overflow));
4668 return BinaryOperator::CreateOr(Ov, NewCmp);
4687 ConstantInt::get(Ty, Ty->getScalarSizeInBits() - 1),
X);
4693 Value *Start =
nullptr, *Step =
nullptr;
4711 return BinaryOperator::CreateOr(
4723 return BinaryOperator::CreateOr(
4731 return Canonicalized;
4733 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
4753 !
Builder.GetInsertBlock()->getParent()->hasFnAttribute(
4754 Attribute::NoImplicitFloat)) {
4768 if ((KnownX.
One & *C2) == *C2)
4769 return BinaryOperator::CreateAnd(
X, ConstantInt::get(Ty, *C1 | *C2));
4778 return BinaryOperator::CreateOr(V, Op1);
4782 return BinaryOperator::CreateOr(Op0, V);
4797 unsigned BitWidth = Ty->getScalarSizeInBits();
4804 I,
Builder.CreateIntrinsic(Ty, Intrinsic::scmp,
4805 {X, Constant::getNullValue(Ty)}));
4815 assert(
I.getOpcode() == Instruction::Xor);
4816 Value *Op0 =
I.getOperand(0);
4817 Value *Op1 =
I.getOperand(1);
4828 return BinaryOperator::CreateXor(
A,
B);
4836 return BinaryOperator::CreateXor(
A,
B);
4844 return BinaryOperator::CreateXor(
A,
B);
4866 assert(
I.getOpcode() == Instruction::Xor &&
I.getOperand(0) ==
LHS &&
4867 I.getOperand(1) ==
RHS &&
"Should be 'xor' with these operands");
4870 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
4871 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
4874 if (LHS0 == RHS1 && LHS1 == RHS0) {
4878 if (LHS0 == RHS0 && LHS1 == RHS1) {
4881 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
4886 const APInt *LC, *RC;
4895 bool TrueIfSignedL, TrueIfSignedR;
4900 return TrueIfSignedL == TrueIfSignedR ?
Builder.CreateIsNeg(XorLR) :
4901 Builder.CreateIsNotNeg(XorLR);
4911 if (CRUnion && CRIntersect)
4912 if (
auto CR = CRUnion->exactIntersectWith(CRIntersect->inverse())) {
4913 if (CR->isFullSet())
4915 if (CR->isEmptySet())
4920 CR->getEquivalentICmp(NewPred, NewC,
Offset);
4927 NewV =
Builder.CreateAdd(NewV, ConstantInt::get(Ty,
Offset));
4928 return Builder.CreateICmp(NewPred, NewV,
4929 ConstantInt::get(Ty, NewC));
4961 ICmpInst *
X =
nullptr, *
Y =
nullptr;
4962 if (OrICmp ==
LHS && AndICmp ==
RHS) {
4967 if (OrICmp ==
RHS && AndICmp ==
LHS) {
4974 Y->setPredicate(
Y->getInversePredicate());
4976 if (!
Y->hasOneUse()) {
4983 Builder.SetInsertPoint(
Y->getParent(), ++(
Y->getIterator()));
4987 Y->replaceUsesWithIf(NotY,
4988 [NotY](Use &U) {
return U.getUser() != NotY; });
5026 Value *NewA = Builder.CreateAnd(
D, NotM);
5027 return BinaryOperator::CreateXor(NewA,
X);
5033 Type *EltTy =
C->getType()->getScalarType();
5037 Value *NotC = Builder.CreateNot(
C);
5038 Value *
RHS = Builder.CreateAnd(
B, NotC);
5039 return BinaryOperator::CreateOr(
LHS,
RHS);
5054 return A ==
C ||
A ==
D ||
B ==
C ||
B ==
D;
5062 Value *NotY = Builder.CreateNot(
Y);
5063 return BinaryOperator::CreateOr(
X, NotY);
5070 Value *NotX = Builder.CreateNot(
X);
5071 return BinaryOperator::CreateOr(
Y, NotX);
5081 assert(
Xor.getOpcode() == Instruction::Xor &&
"Expected an xor instruction.");
5087 Value *Op0 =
Xor.getOperand(0), *Op1 =
Xor.getOperand(1);
5095 Op1->
hasNUses(2) && *ShAmt == Ty->getScalarSizeInBits() - 1 &&
5100 Value *IsNeg = Builder.CreateIsNeg(
A);
5103 Value *NegA =
Add->hasNoUnsignedWrap()
5105 : Builder.CreateNeg(
A,
"",
Add->hasNoSignedWrap());
5114 return I &&
I->getInsertionPointAfterDef() &&
5122 auto InsertPt =
I->getInsertionPointAfterDef();
5124 "freelyInvert requires an instruction with a valid insertion point");
5127 Op->replaceUsesWithIf(NotOp,
5128 [NotOp](
Use &U) {
return U.getUser() != NotOp; });
5169 auto InsertPt =
I.getInsertionPointAfterDef();
5170 assert(InsertPt &&
"sinkNotIntoLogicalOp requires an instruction with a "
5171 "valid insertion point");
5172 Builder.SetInsertPoint(*InsertPt);
5175 NewLogicOp =
Builder.CreateBinOp(NewOpc, Op0, Op1,
I.getName() +
".not");
5178 Builder.CreateLogicalOp(NewOpc, Op0, Op1,
I.getName() +
".not", &
I);
5180 SI->swapProfMetadata();
5204 Value *NotOp0 =
nullptr;
5205 Value *NotOp1 =
nullptr;
5206 Value **OpToInvert =
nullptr;
5223 Builder.SetInsertPoint(*
I.getInsertionPointAfterDef());
5226 NewBinOp =
Builder.CreateBinOp(NewOpc, Op0, Op1,
I.getName() +
".not");
5228 NewBinOp =
Builder.CreateLogicalOp(NewOpc, Op0, Op1,
I.getName() +
".not");
5251 Type *Ty =
I.getType();
5254 Value *NotY = Builder.CreateNot(
Y,
Y->getName() +
".not");
5255 return BinaryOperator::CreateOr(
X, NotY);
5258 Value *NotY = Builder.CreateNot(
Y,
Y->getName() +
".not");
5261 SI->swapProfMetadata();
5269 return BinaryOperator::CreateAnd(
X, NotY);
5275 SI->swapProfMetadata();
5280 BinaryOperator *NotVal;
5287 return BinaryOperator::CreateAnd(DecX, NotY);
5292 return BinaryOperator::CreateAShr(
X,
Y);
5298 return BinaryOperator::CreateAShr(
X,
Y);
5305 return new SExtInst(IsNotNeg, Ty);
5332 return BinaryOperator::CreateAdd(
Builder.CreateNot(
X),
Y);
5355 return new BitCastInst(
X, Ty);
5361 X->getType()->isIntOrIntVectorTy(1)) {
5365 return new BitCastInst(Sext, Ty);
5376 if (
II &&
II->hasOneUse()) {
5380 Value *InvMaxMin =
Builder.CreateBinaryIntrinsic(InvID,
X, NotY);
5384 if (
II->getIntrinsicID() == Intrinsic::is_fpclass) {
5387 1, ConstantInt::get(ClassMask->
getType(),
5403 Value *TV = Sel->getTrueValue();
5404 Value *FV = Sel->getFalseValue();
5407 bool InvertibleT = (CmpT && CmpT->hasOneUse()) ||
isa<Constant>(TV);
5408 bool InvertibleF = (CmpF && CmpF->hasOneUse()) ||
isa<Constant>(FV);
5409 if (InvertibleT && InvertibleF) {
5411 CmpT->setPredicate(CmpT->getInversePredicate());
5415 CmpF->setPredicate(CmpF->getInversePredicate());
5446 Value *NotC = Builder.CreateNot(AddC);
5449 return BinaryOperator::CreateAnd(NewSub, Mask);
5460 SQ.getWithInstruction(&
I)))
5490 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5498 return BinaryOperator::CreateXor(XorAC,
Y);
5501 return BinaryOperator::CreateXor(XorBC,
X);
5511 return BinaryOperator::CreateDisjointOr(Op0, Op1);
5513 return BinaryOperator::CreateOr(Op0, Op1);
5530 return BinaryOperator::CreateXor(
5553 *CA ==
X->getType()->getScalarSizeInBits() - 1 &&
5557 return createSelectInstWithUnknownProfile(IsNotNeg, Op1,
5562 Type *Ty =
I.getType();
5570 return BinaryOperator::CreateSub(ConstantInt::get(Ty, *
C + *RHSC),
X);
5574 return BinaryOperator::CreateAdd(
X, ConstantInt::get(Ty, *
C + *RHSC));
5579 return BinaryOperator::CreateXor(
X, ConstantInt::get(Ty, *
C ^ *RHSC));
5585 if (
II &&
II->hasOneUse() && *RHSC == Ty->getScalarSizeInBits() - 1) {
5587 if ((IID == Intrinsic::ctlz || IID == Intrinsic::cttz) &&
5590 IID = (IID == Intrinsic::ctlz) ? Intrinsic::cttz : Intrinsic::ctlz;
5603 return BinaryOperator::CreateShl(NotX, ConstantInt::get(Ty, *
C));
5609 return BinaryOperator::CreateLShr(NotX, ConstantInt::get(Ty, *
C));
5627 !
Builder.GetInsertBlock()->getParent()->hasFnAttribute(
5628 Attribute::NoImplicitFloat)) {
5651 auto *Opnd0 =
Builder.CreateLShr(
X, C2);
5652 Opnd0->takeName(Op0);
5653 return BinaryOperator::CreateXor(Opnd0, ConstantInt::get(Ty, FoldConst));
5666 return BinaryOperator::CreateAnd(
X,
Builder.CreateNot(Op0));
5670 return BinaryOperator::CreateAnd(
X,
Builder.CreateNot(Op1));
5675 return BinaryOperator::CreateAnd(Op0,
Builder.CreateNot(
X));
5683 return BinaryOperator::CreateAnd(Op1,
Builder.CreateNot(
X));
5689 return BinaryOperator::CreateXor(
5695 return BinaryOperator::CreateXor(
5701 return BinaryOperator::CreateOr(
A,
B);
5705 return BinaryOperator::CreateOr(
A,
B);
5715 return BinaryOperator::CreateOr(
A,
B);
5730 if (
B ==
C ||
B ==
D)
5736 return BinaryOperator::CreateAnd(
Builder.CreateXor(
B,
C), NotA);
5741 if (
I.getType()->isIntOrIntVectorTy(1) &&
5746 if (
B ==
C ||
B ==
D) {
5756 return MDFrom ==
nullptr
5757 ? createSelectInstWithUnknownProfile(
A, NotB,
C)
5764 if (
Value *V = foldXorOfICmps(LHS, RHS,
I))
5767 if (
Instruction *CastedXor = foldCastedBitwiseLogic(
I))
5780 return BinaryOperator::CreateXor(
Builder.CreateXor(
X,
Y), C1);
5786 return Canonicalized;
5788 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
5791 if (
Instruction *Folded = canonicalizeConditionalNegationViaMathToSelect(
I))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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 GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isSigned(unsigned Opcode)
static Value * foldBitmaskMul(Value *Op0, Value *Op1, InstCombiner::BuilderTy &Builder)
(A & N) * C + (A & M) * C -> (A & (N + M)) & C This also accepts the equivalent select form of (A & N...
static unsigned conjugateICmpMask(unsigned Mask)
Convert an analysis of a masked ICmp into its equivalent if all boolean operations had the opposite s...
static Instruction * foldNotXor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static Value * foldLogOpOfMaskedICmps(Value *LHS, Value *RHS, bool IsAnd, bool IsLogical, InstCombiner::BuilderTy &Builder, const SimplifyQuery &Q)
Try to fold (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E) into a single (icmp(A & X) ==/!...
static Value * getFCmpValue(unsigned Code, Value *LHS, Value *RHS, InstCombiner::BuilderTy &Builder, FMFSource FMF)
This is the complement of getFCmpCode, which turns an opcode and two operands into either a FCmp inst...
static bool matchIsFPClassLikeFCmp(Value *Op, Value *&ClassVal, uint64_t &ClassMask)
Match an fcmp against a special value that performs a test possible by llvm.is.fpclass.
static 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 * foldAndOrOfICmpEqConstantAndICmp(CmpPredicate PredL, Value *LHS0, Value *LHS1, bool LHSOneUse, CmpPredicate PredR, Value *RHS0, Value *RHS1, bool RHSOneUse, bool IsAnd, bool IsLogical, IRBuilderBase &Builder)
static Instruction * foldOrToXor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static Value * simplifyAndOrWithOpReplaced(Value *V, Value *Op, Value *RepOp, bool SimplifyOnly, InstCombinerImpl &IC, unsigned Depth=0)
static Instruction * matchDeMorgansLaws(BinaryOperator &I, InstCombiner &IC)
Match variations of De Morgan's Laws: (~A & ~B) == (~(A | B)) (~A | ~B) == (~(A & B))
static Value * foldLogOpOfMaskedICmpsAsymmetric(Value *LHS, Value *RHS, bool IsAnd, Value *A, Value *B, Value *C, Value *D, Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR, unsigned LHSMask, unsigned RHSMask, InstCombiner::BuilderTy &Builder)
Try to fold (icmp(A & B) ==/!= 0) &/| (icmp(A & D) ==/!= E) into a single (icmp(A & X) ==/!...
static Value * FoldOrOfSelectSmaxToAbs(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
Fold select(X >s 0, 0, -X) | smax(X, 0) --> abs(X) select(X <s 0, -X, 0) | smax(X,...
static Instruction * foldAndToXor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static unsigned getMaskedICmpType(Value *A, Value *B, Value *C, ICmpInst::Predicate Pred)
Return the set of patterns (from MaskedICmpType) that (icmp SCC (A & B), C) satisfies.
static Instruction * foldXorToXor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
A ^ B can be specified using other logic ops in a variety of patterns.
static bool canNarrowShiftAmt(Constant *C, unsigned BitWidth)
Return true if a constant shift amount is always less than the specified bit-width.
static Value * foldIsPowerOf2(CmpPredicate PredL, Value *LHS0, Value *LHS1, CmpPredicate PredR, Value *RHS0, Value *RHS1, bool JoinedByAnd, InstCombiner::BuilderTy &Builder, InstCombinerImpl &IC)
Reduce a pair of compares that check if a value has exactly 1 bit set.
static Value * foldIsPowerOf2OrZero(CmpPredicate PredL, Value *LHS0, Value *LHS1, CmpPredicate PredR, Value *RHS0, Value *RHS1, bool IsAnd, InstCombiner::BuilderTy &Builder, InstCombinerImpl &IC)
Fold (icmp eq ctpop(X) 1) | (icmp eq X 0) into (icmp ult ctpop(X) 2) and fold (icmp ne ctpop(X) 1) & ...
static Instruction * foldLogicCastConstant(BinaryOperator &Logic, CastInst *Cast, InstCombinerImpl &IC)
Fold {and,or,xor} (cast X), C.
static Value * foldPowerOf2AndShiftedMask(Value *Cmp0, Value *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 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 * foldOrUnsignedUMulOverflowICmp(BinaryOperator &I, InstCombiner::BuilderTy &Builder, const DataLayout &DL)
Fold Res, Overflow = (umul.with.overflow x c1); (or Overflow (ugt Res c2)) --> (ugt x (c2/c1)).
static Value * freelyInvert(InstCombinerImpl &IC, Value *Op, Instruction *IgnoredUser)
static Value * foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(Value *LHS, Value *RHS, bool IsAnd, Value *A, Value *B, Value *D, Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR, InstCombiner::BuilderTy &Builder)
Try to fold (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E) into a single (icmp(A & X) ==/!...
static std::optional< IntPart > matchIntPart(Value *V)
Match an extraction of bits from an integer.
static Instruction * canonicalizeLogicFirst(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static Instruction * reassociateFCmps(BinaryOperator &BO, InstCombiner::BuilderTy &Builder)
This a limited reassociation for a special case (see above) where we are checking if two values are e...
static Value * getNewICmpValue(unsigned Code, bool Sign, Value *LHS, Value *RHS, InstCombiner::BuilderTy &Builder)
This is the complement of getICmpCode, which turns an opcode and two operands into either a constant ...
static Value * extractIntPart(const IntPart &P, IRBuilderBase &Builder)
Materialize an extraction of bits from an integer in IR.
static bool matchUnorderedInfCompare(FCmpInst::Predicate P, Value *LHS, Value *RHS)
Matches fcmp u__ x, +/-inf.
static bool matchIsNotNaN(FCmpInst::Predicate P, Value *LHS, Value *RHS)
Matches canonical form of isnan, fcmp ord x, 0.
static bool areInverseVectorBitmasks(Constant *C1, Constant *C2)
If all elements of two constant vectors are 0/-1 and inverses, return true.
MaskedICmpType
Classify (icmp eq (A & B), C) and (icmp ne (A & B), C) as matching patterns that can be simplified.
static Instruction * foldComplexAndOrPatterns(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
Try folding relatively complex patterns for both And and Or operations with all And and Or swapped.
static bool matchZExtedSubInteger(Value *V, Value *&Int, APInt &Mask, uint64_t &Offset, bool &IsShlNUW, bool &IsShlNSW)
Match V as "lshr -> mask -> zext -> shl".
static Value * foldAndOrOfICmpsWithPow2AndWithZero(InstCombiner::BuilderTy &Builder, CmpPredicate PredL, Value *LHS0, Value *LHS1, bool LHSOneUse, CmpPredicate PredR, Value *RHS0, Value *RHS1, bool RHSOneUse, bool IsAnd, const SimplifyQuery &Q)
static Value * foldUnsignedUnderflowCheck(CmpPredicate PredL, Value *LHS0, Value *LHS1, bool LHSOneUse, CmpPredicate PredR, Value *RHS0, Value *RHS1, bool RHSOneUse, 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 * foldRoundUpToPow2Alignment(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
The pattern div_ceil(X, P) * P, where P is a power of 2, lowers to the following conditional round-up...
static std::optional< DecomposedBitMaskMul > matchBitmaskMul(Value *V)
static Value * foldOrOfInversions(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static bool matchSubIntegerPackFromVector(Value *V, Value *&Vec, int64_t &VecOffset, SmallBitVector &Mask, const DataLayout &DL)
Match V as "shufflevector -> bitcast" or "extractelement -> zext -> shl" patterns,...
static Instruction * matchFunnelShift(Instruction &Or, InstCombinerImpl &IC)
Match UB-safe variants of the funnel shift intrinsic.
static Instruction * reassociateForUses(BinaryOperator &BO, InstCombinerImpl::BuilderTy &Builder)
Try to reassociate a pair of binops so that values with one use only are part of the same instruction...
static Value * matchOrConcat(Instruction &Or, InstCombiner::BuilderTy &Builder)
Attempt to combine or(zext(x),shl(zext(y),bw/2) concat packing patterns.
static Instruction * foldMaskedAddXorPattern(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static Instruction * foldBitwiseLogicWithIntrinsics(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static Value * foldSignedTruncationCheck(CmpPredicate PredL, Value *LHS0, Value *LHS1, CmpPredicate PredR, Value *RHS0, Value *RHS1, Instruction &CxtI, InstCombiner::BuilderTy &Builder)
General pattern: X & Y.
static std::optional< std::pair< unsigned, unsigned > > getMaskedTypeForICmpPair(Value *&A, Value *&B, Value *&C, Value *&D, Value *&E, Value *LHS, Value *RHS, ICmpInst::Predicate &PredL, ICmpInst::Predicate &PredR)
Handle (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E).
static Value * foldAndOrOfICmpsWithConstEq(CmpPredicate PredL, Value *LHS0, Value *LHS1, Value *LHS, CmpPredicate PredR, Value *RHS0, Value *RHS1, bool RHSOneUse, bool IsAnd, bool IsLogical, InstCombiner::BuilderTy &Builder, const SimplifyQuery &Q, Instruction &I)
Reduce logic-of-compares with equality to a constant by substituting a common operand with the consta...
static Instruction * foldIntegerPackFromVector(Instruction &I, InstCombiner::BuilderTy &Builder, const DataLayout &DL)
Try to fold the join of two scalar integers whose contents are packed elements of the same vector.
static Value * foldIntegerRepackThroughZExt(Value *Lhs, Value *Rhs, InstCombiner::BuilderTy &Builder)
Try to fold the join of two scalar integers whose bits are unpacked and zexted from the same source i...
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
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > & Cond
This file implements the SmallBitVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static constexpr int Concat[]
static LLVM_ABI bool hasSignBitInMSB(const fltSemantics &)
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.
LLVM_ABI APInt udiv(const APInt &RHS) const
Unsigned division operation.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
unsigned countLeadingOnes() const
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
LLVM_ABI APInt usub_ov(const APInt &RHS, bool &Overflow) const
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isSignMask() const
Check if the APInt's value is returned by getSignMask.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
LLVM_ABI APInt sadd_ov(const APInt &RHS, bool &Overflow) const
bool intersects(const APInt &RHS) const
This operation tests if there are any pairs of corresponding bits between this APInt and RHS that are...
int32_t exactLogBase2() const
LLVM_ABI APInt reverseBits() const
LLVM_ABI APInt uadd_ov(const APInt &RHS, bool &Overflow) const
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countLeadingZeros() const
bool ule(const APInt &RHS) const
Unsigned less or equal comparison.
APInt shl(unsigned shiftAmt) const
Left-shift function.
LLVM_ABI APInt byteSwap() const
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
LLVM_ABI APInt ssub_ov(const APInt &RHS, bool &Overflow) const
static APInt getBitsSetFrom(unsigned numBits, unsigned loBit)
Constructs an APInt value that has a contiguous range of bits set.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
void clearSignBit()
Set the sign bit to 0.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM_ABI bool isSigned() const
Whether the intrinsic is signed or unsigned.
LLVM_ABI Instruction::BinaryOps getBinaryOp() const
Returns the binary operation underlying the intrinsic.
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
static BinaryOperator * CreateWithCopiedFlags(BinaryOps Opc, Value *V1, Value *V2, Value *CopyO, const Twine &Name="", InsertPosition InsertBefore=nullptr)
This class represents a no-op cast from one type to another.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
This is the base class for all instructions that perform data casts.
Type * getSrcTy() const
Return the source type, as a convenience.
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
Type * getDestTy() const
Return the destination type, as a convenience.
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ ICMP_ULT
unsigned less than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ ICMP_SGE
signed greater or equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
static LLVM_ABI bool isUnordered(Predicate predicate)
Determine if the predicate is an unordered operation.
static Predicate getOrderedPredicate(Predicate Pred)
Returns the ordered variant of a floating point compare.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
static LLVM_ABI CmpPredicate getInverse(CmpPredicate P)
Get the inverse predicate of a CmpPredicate.
CmpInst::Predicate dropSameSign() const
Drops samesign information.
bool hasSameSign() const
Query samesign information, for optimizations.
static LLVM_ABI CmpPredicate getSwapped(CmpPredicate P)
Get the swapped predicate of a CmpPredicate.
static LLVM_ABI Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI Constant * getNot(Constant *C)
static LLVM_ABI Constant * getXor(Constant *C1, Constant *C2)
static LLVM_ABI Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getExactLogBase2(Constant *C)
If C is a scalar/fixed width vector of known powers of 2, then this function returns a new scalar/fix...
static LLVM_ABI ConstantFP * getZero(Type *Ty, bool Negative=false)
This is the shared class of boolean and integer constants.
bool isMinusOne() const
This function will return true iff every bit in this constant is set to true.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
const APInt & getValue() const
Return the constant as an APInt value reference.
LLVM_ABI std::optional< ConstantRange > exactUnionWith(const ConstantRange &CR) const
Union the two ranges and return the result if it can be represented exactly, otherwise return std::nu...
LLVM_ABI ConstantRange subtract(const APInt &CI) const
Subtract the specified constant from the endpoints of this constant range.
static LLVM_ABI ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)
Produce the exact range such that all values in the returned range satisfy the given predicate with a...
LLVM_ABI std::optional< ConstantRange > exactIntersectWith(const ConstantRange &CR) const
Intersect the two ranges and return the result if it can be represented exactly, otherwise return std...
This is an important base class in LLVM.
static LLVM_ABI Constant * replaceUndefsWith(Constant *C, Constant *Replacement)
Try to replace undefined constant C or undefined elements in C with Replacement.
static LLVM_ABI Constant * mergeUndefsWith(Constant *C, Constant *Other)
Merges undefs of a Constant with another Constant, along with the undefs already present.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
A parsed version of the target data layout string in and methods for querying it.
This instruction compares its operands according to the predicate given to the constructor.
This provides a helper for copying FMF from an instruction or setting specified flags.
static FMFSource intersect(Value *A, Value *B)
Intersect the FMF from two instructions.
void setNoNaNs(bool B=true)
void setNoInfs(bool B=true)
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.
static bool isEquality(Predicate P)
Return true if this predicate is either EQ or NE.
Common base class shared among various IRBuilders.
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
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).
Instruction * foldBinOpSelectBinOp(BinaryOperator &Op)
In some cases it is beneficial to fold a select into a binary operator.
bool sinkNotIntoLogicalOp(Instruction &I)
std::optional< std::pair< Intrinsic::ID, SmallVector< Value *, 3 > > > convertOrOfShiftsToFunnelShift(Instruction &Or)
Value * simplifyRangeCheck(CmpPredicate PredL, Value *LHS0, Value *LHS1, CmpPredicate PredR, Value *RHS0, Value *RHS1, Instruction *CxtI, bool Inverted)
Try to fold a signed range checked with lower bound 0 to an unsigned icmp.
Instruction * visitAnd(BinaryOperator &I)
bool sinkNotIntoOtherHandOfLogicalOp(Instruction &I)
Instruction * foldBinopWithPhiOperands(BinaryOperator &BO)
For a binary operator with 2 phi operands, try to hoist the binary operation before the phi.
Instruction * foldAddLikeCommutative(Value *LHS, Value *RHS, bool NSW, bool NUW)
Common transforms for add / disjoint or.
Instruction * tryFoldInstWithCtpopWithNot(Instruction *I)
Instruction * FoldOrOfLogicalAnds(Value *Op0, Value *Op1)
Value * SimplifyAddWithRemainder(BinaryOperator &I)
Tries to simplify add operations using the definition of remainder.
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.
const DataLayout & getDataLayout() const
bool isFreeToInvert(Value *V, bool WillInvertAllUses, bool &DoesConsume)
Return true if the specified value is free to invert (apply ~ to).
unsigned ComputeNumSignBits(const Value *Op, const Instruction *CxtI=nullptr, unsigned Depth=0) const
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
InstructionWorklist & Worklist
A worklist of the instructions that need to be simplified.
void computeKnownBits(const Value *V, KnownBits &Known, const Instruction *CxtI, unsigned Depth=0) const
static Value * peekThroughBitcast(Value *V, bool OneUseOnly=false)
Return the source operand of a potentially bitcasted value while optionally checking if it has one us...
IRBuilder< TargetFolder, IRBuilderInstCombineInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
bool canFreelyInvertAllUsersOf(Instruction *V, Value *IgnoredUser)
Given i1 V, can every user of V be freely adapted if V is changed to !V ?
void addToWorklist(Instruction *I)
static Value * stripSignOnlyFPOps(Value *Val)
Ignore all operations which only change the sign of a value, returning the underlying magnitude value...
bool MaskedValueIsZero(const Value *V, const APInt &Mask, const Instruction *CxtI=nullptr, unsigned Depth=0) const
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
const SimplifyQuery & getSimplifyQuery() const
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, const Instruction *CxtI=nullptr, unsigned Depth=0)
LLVM_ABI void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
LLVM_ABI bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
LLVM_ABI bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
LLVM_ABI void swapProfMetadata()
If the instruction has "branch_weights" MD_prof metadata and the MDNode has three operands (including...
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.
This class represents the LLVM 'select' instruction.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() 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.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
LLVM_ABI const fltSemantics & getFltSemantics() const
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
iterator_range< user_iterator > users()
LLVM_ABI bool hasNUsesOrMore(unsigned N) const
Return true if this value has N uses or more.
LLVM_ABI bool hasNUses(unsigned N) const
Return true if this Value has exactly N uses.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
Represents an op.with.overflow intrinsic.
This class represents zero extension of integer types.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const APInt & umin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be unsigned.
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.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
auto m_PosZeroFP()
Matches a floating-point positive zero.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
AllOnesConstantMatch m_AllOnes()
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
match_unless< Pattern > m_Unless(const Pattern &P)
Match if the inner matcher does NOT match.
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
match_combine_and< Ty... > m_CombineAnd(const Ty &...Ps)
Combine pattern matchers matching all of Ps patterns.
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)
auto m_BSwap(const Opnd0 &Op0)
cst_pred_ty< is_negative > m_Negative()
Match an integer or vector of negative values.
auto m_Cmp()
Matches any compare instruction and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
auto m_BitReverse(const Opnd0 &Op0)
CmpClass_match< LHS, RHS, FCmpInst > m_FCmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
cst_pred_ty< is_sign_mask > m_SignMask()
Match an integer or vector with only the sign bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
cstfp_pred_ty< is_inf > m_Inf()
Match a positive or negative infinity FP constant.
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.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
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)
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
auto m_ConstantExpr()
Match a constant expression or a constant that contains a constant expression.
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)
match_bind< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
cst_pred_ty< is_shifted_mask > m_ShiftedMask()
match_deferred< 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()...
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
DisjointOr_match< LHS, RHS > m_DisjointOr(const LHS &L, const RHS &R)
specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)
ap_match< APFloat > m_APFloatAllowPoison(const APFloat *&Res)
Match APFloat while allowing poison in splat vector constants.
TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)
Matches ExtractElementInst.
cst_pred_ty< is_nonnegative > m_NonNegative()
Match an integer or vector of non-negative values.
auto m_SMax(const Opnd0 &Op0, const Opnd1 &Op1)
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.
auto m_BinOp()
Match an arbitrary binary operation and ignore it.
match_combine_or< CastInst_match< OpTy, SExtInst >, OpTy > m_SExtOrSelf(const OpTy &Op)
ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)
Match a single index ExtractValue instruction.
BinOpPred_match< LHS, RHS, is_logical_shift_op > m_LogicalShift(const LHS &L, const RHS &R)
Matches logical shift operations.
ICmpLike_match< LHS, RHS > m_ICmpLike(CmpPredicate &Pred, const LHS &L, const RHS &R)
auto m_Value()
Match an arbitrary value and ignore it.
ShiftLike_match< LHS, Instruction::Shl > m_ShlOrSelf(const LHS &L, uint64_t &R)
Matches shl L, ConstShAmt or L itself (R will be set to zero in this case).
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.
auto m_Ctpop(const Opnd0 &Op0)
SpecificCmpClass_match< LHS, RHS, CmpInst > m_SpecificCmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
auto m_Constant()
Match an arbitrary Constant and ignore it.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
match_bind< WithOverflowInst > m_WithOverflowInst(WithOverflowInst *&I)
Match a with overflow intrinsic, capturing it if we match.
SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
cst_pred_ty< is_negated_power2 > m_NegatedPower2()
Match a integer or vector negated power-of-2.
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
DisjointOr_match< LHS, RHS, true > m_c_DisjointOr(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
SpecificCmpClass_match< LHS, RHS, FCmpInst > m_SpecificFCmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
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< CastInst_match< OpTy, SExtInst >, NNegZExt_match< OpTy > > m_SExtLike(const OpTy &Op)
Match either "sext" or "zext nneg".
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
auto m_c_MaxOrMin(const LHS &L, const RHS &R)
cst_pred_ty< is_maxsignedvalue > m_MaxSignedValue()
Match an integer or vector with values having all bits except for the high bit set (0x7f....
AnyBinaryOp_match< LHS, RHS, true > m_c_BinOp(const LHS &L, const RHS &R)
Matches a BinaryOperator with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > > m_ZExtOrSExt(const OpTy &Op)
BinOpPred_match< LHS, RHS, is_shift_op > m_Shift(const LHS &L, const RHS &R)
Matches shift operations.
LogicalOp_match< LHS, RHS, Instruction::And, true > m_c_LogicalAnd(const LHS &L, const RHS &R)
Matches L && R with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
ElementWiseBitCast_match< OpTy > m_ElementWiseBitCast(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &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.
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
NodeAddr< CodeNode * > Code
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI Intrinsic::ID getInverseMinMaxIntrinsic(Intrinsic::ID MinMaxID)
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
LLVM_ABI Constant * getPredForFCmpCode(unsigned Code, Type *OpTy, CmpInst::Predicate &Pred)
This is the complement of getFCmpCode.
LLVM_ABI cl::opt< bool > ProfcheckDisableMetadataFixes
LLVM_ABI bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS, bool &TrueIfSigned)
Given an exploded icmp instruction, return true if the comparison only checks the sign bit.
@ Known
Known to have no common set bits.
LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I, StringRef PassName, const Function *F=nullptr)
Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch weights in the new instruct...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool predicatesFoldable(CmpInst::Predicate P1, CmpInst::Predicate P2)
Return true if both predicates match sign or if at least one of them is an equality comparison (which...
LLVM_ABI Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Instruction *I=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
LLVM_ABI Value * simplifyOrInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an Or, fold the result or return null.
LLVM_ABI Value * simplifyXorInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an Xor, fold the result or return null.
LLVM_ABI bool isGuaranteedNotToBeUndef(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be undef, but may be poison.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI bool matchSimpleRecurrence(const PHINode *P, BinaryOperator *&BO, Value *&Start, Value *&Step)
Attempt to match a simple first order recurrence cycle of the form: iv = phi Ty [Start,...
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI bool isKnownNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the given value is known be negative (i.e.
LLVM_ABI Constant * getLosslessUnsignedTrunc(Constant *C, Type *DestTy, const DataLayout &DL, PreservedCastFlags *Flags=nullptr)
LLVM_ABI bool recognizeBSwapOrBitReverseIdiom(Instruction *I, bool MatchBSwaps, bool MatchBitReversals, SmallVectorImpl< Instruction * > &InsertedInsts)
Try to match a bswap or bitreverse idiom.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI Value * simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an ICmpInst, fold the result or return null.
LLVM_ABI Constant * getLosslessSignedTrunc(Constant *C, Type *DestTy, const DataLayout &DL, PreservedCastFlags *Flags=nullptr)
LLVM_ABI Value * simplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an And, fold the result or return null.
LLVM_ABI bool isKnownInversion(const Value *X, const Value *Y)
Return true iff:
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
constexpr int PoisonMaskElem
LLVM_ABI Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
LLVM_ABI std::optional< DecomposedBitTest > decomposeBitTest(Value *Cond, bool LookThroughTrunc=true, bool AllowNonZeroC=false, bool DecomposeAnd=false)
Decompose an icmp into the form ((X & Mask) pred C) if possible.
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
APFloat neg(APFloat X)
Returns the negated value of the argument.
LLVM_ABI unsigned getICmpCode(CmpInst::Predicate Pred)
Encode a icmp predicate into a three bit mask.
LLVM_ABI bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Return true if the given value is known to have exactly one bit set when defined.
LLVM_ABI bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
std::pair< Value *, FPClassTest > fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS, Value *RHS, bool LookThroughSrc=true)
Returns a pair of values, which if passed to llvm.is.fpclass, returns the same result as an fcmp with...
unsigned getFCmpCode(CmpInst::Predicate CC)
Similar to getICmpCode but for FCmpInst.
LLVM_ABI std::optional< DecomposedBitTest > decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate Pred, bool LookThroughTrunc=true, bool AllowNonZeroC=false, bool DecomposeAnd=false)
Decompose an icmp into the form ((X & Mask) pred C) if possible.
LLVM_ABI Constant * getPredForICmpCode(unsigned Code, bool Sign, Type *OpTy, CmpInst::Predicate &Pred)
This is the complement of getICmpCode.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isCombineableWith(const DecomposedBitMaskMul Other)
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
SimplifyQuery getWithInstruction(const Instruction *I) const