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));
363 return Builder.CreateICmp(PredR,
And,
E);
385 const APInt *BCst, *DCst, *OrigECst;
396 APInt ECst = *OrigECst;
402 if (*BCst == 0 || *DCst == 0)
412 !Builder.GetInsertBlock()->getParent()->hasFnAttribute(
413 Attribute::StrictFP)) {
415 if (!Ty->isIEEELikeFPTy())
421 APInt FractionBits = ~ExpBits;
423 if (*BCst != FractionBits)
448 if ((((*BCst & *DCst) & ECst) == 0) &&
449 (*BCst & (*BCst ^ *DCst)).isPowerOf2()) {
450 APInt BorD = *BCst | *DCst;
451 APInt BandBxorDorE = (*BCst & (*BCst ^ *DCst)) | ECst;
452 Value *NewMask = ConstantInt::get(
A->getType(), BorD);
453 Value *NewMaskedValue = ConstantInt::get(
A->getType(), BandBxorDorE);
454 Value *NewAnd = Builder.CreateAnd(
A, NewMask);
455 return Builder.CreateICmp(NewCC, NewAnd, NewMaskedValue);
458 auto IsSubSetOrEqual = [](
const APInt *
C1,
const APInt *C2) {
459 return (*
C1 & *C2) == *
C1;
461 auto IsSuperSetOrEqual = [](
const APInt *
C1,
const APInt *C2) {
462 return (*
C1 & *C2) == *C2;
471 if (!IsSubSetOrEqual(BCst, DCst) && !IsSuperSetOrEqual(BCst, DCst))
483 if (IsSubSetOrEqual(BCst, DCst))
484 return ConstantInt::get(
LHS->getType(), !IsAnd);
494 if (IsSuperSetOrEqual(BCst, DCst))
500 assert(IsSubSetOrEqual(BCst, DCst) &&
"Precondition due to above code");
501 if ((*BCst & ECst) != 0)
508 return ConstantInt::get(
LHS->getType(), !IsAnd);
521 "Expected equality predicates for masked type of icmps.");
533 LHS,
RHS, IsAnd, IsLogical,
A,
B,
D,
E, PredL, PredR, Builder)) {
538 RHS,
LHS, IsAnd,
false,
A,
D,
B,
C, PredR, PredL,
552 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *
E =
nullptr;
554 std::optional<std::pair<unsigned, unsigned>> MaskPair =
559 "Expected equality predicates for masked type of icmps.");
560 unsigned LHSMask = MaskPair->first;
561 unsigned RHSMask = MaskPair->second;
562 unsigned Mask = LHSMask & RHSMask;
567 A,
B,
C,
D,
E, PredL, PredR,
568 LHSMask, RHSMask, Builder))
597 Value *NewOr = Builder.CreateOr(
B,
D);
598 Value *NewAnd = Builder.CreateAnd(
A, NewOr);
603 return Builder.CreateICmp(NewCC, NewAnd,
Zero);
610 Value *NewOr = Builder.CreateOr(
B,
D);
611 Value *NewAnd = Builder.CreateAnd(
A, NewOr);
612 return Builder.CreateICmp(NewCC, NewAnd, NewOr);
619 Value *NewAnd1 = Builder.CreateAnd(
B,
D);
620 Value *NewAnd2 = Builder.CreateAnd(
A, NewAnd1);
621 return Builder.CreateICmp(NewCC, NewAnd2,
A);
624 const APInt *ConstB, *ConstD;
632 APInt NewMask = *ConstB & *ConstD;
633 if (NewMask == *ConstB)
635 if (NewMask == *ConstD)
645 APInt NewMask = *ConstB | *ConstD;
646 if (NewMask == *ConstB)
648 if (NewMask == *ConstD)
675 const APInt *OldConstC, *OldConstE;
681 const APInt ConstC = PredL !=
CC ? *ConstB ^ *OldConstC : *OldConstC;
682 const APInt ConstE = PredR !=
CC ? *ConstD ^ *OldConstE : *OldConstE;
684 if (((*ConstB & *ConstD) & (ConstC ^ ConstE)).getBoolValue())
685 return IsNot ? nullptr : ConstantInt::get(
LHS->getType(), !IsAnd);
688 !ConstD->isSubsetOf(*ConstB))
693 BD = *ConstB & *ConstD;
694 CE = ConstC & ConstE;
696 BD = *ConstB | *ConstD;
697 CE = ConstC | ConstE;
699 Value *NewAnd = Builder.CreateAnd(
A, BD);
700 Value *CEVal = ConstantInt::get(
A->getType(), CE);
701 return Builder.CreateICmp(
CC, NewAnd, CEVal);
705 return FoldBMixed(NewCC,
false);
707 return FoldBMixed(NewCC,
true);
722 D = Builder.CreateFreeze(
D);
723 Value *Mask = Builder.CreateOr(
B,
D);
725 return Builder.CreateICmp(NewCC,
Masked, Mask);
784 if (!
Known.isNonNegative())
826 if (!LHSOneUse || !RHSOneUse || !
match(LHS1,
m_Zero()) || RHS0 != LHS0 ||
830 Value *
And = Builder.CreateAnd(LHS0, RHS1);
831 return Builder.CreateICmp(
Pred,
And, LHS0);
874 APInt &SignBitMask) ->
bool {
875 const APInt *I01, *I1;
889 if (tryToMatchSignedTruncationCheck(PredR, RHS0, RHS1, X1, HighestBit)) {
893 }
else if (!tryToMatchSignedTruncationCheck(PredL, LHS0, LHS1, X1,
897 assert(HighestBit.
isPowerOf2() &&
"expected to be power of two (non-zero)");
901 APInt &UnsetBitsMask) ->
bool {
909 UnsetBitsMask = Res->Mask;
919 if (!tryToDecompose(PredR, RHS0, RHS1, X0, UnsetBitsMask))
922 assert(!UnsetBitsMask.
isZero() &&
"empty mask makes no sense.");
937 APInt SignBitsMask = ~(HighestBit - 1U);
944 if (!UnsetBitsMask.
isSubsetOf(SignBitsMask)) {
945 APInt OtherHighestBit = (~UnsetBitsMask) + 1U;
953 return Builder.CreateICmpULT(
X, ConstantInt::get(
X->getType(), HighestBit),
954 CtxI.
getName() +
".simplified");
974 CtPop->dropPoisonGeneratingAnnotations();
976 return Builder.CreateICmpUGT(CtPop, ConstantInt::get(CtPop->getType(), 1));
980 CtPop->dropPoisonGeneratingAnnotations();
982 return Builder.CreateICmpULT(CtPop, ConstantInt::get(CtPop->getType(), 2));
1008 CtPop->dropPoisonGeneratingAnnotations();
1010 return Builder.CreateICmpEQ(CtPop, ConstantInt::get(CtPop->getType(), 1));
1018 CtPop->dropPoisonGeneratingAnnotations();
1020 return Builder.CreateICmpNE(CtPop, ConstantInt::get(CtPop->getType(), 1));
1034 "Expected equality predicates for masked type of icmps.");
1054 const APInt *BCst, *DCst, *ECst;
1068 if (!BFVTy || !BConst || !DConst || !EConst)
1071 for (
unsigned I = 0;
I != BFVTy->getNumElements(); ++
I) {
1072 const auto *BElt = BConst->getAggregateElement(
I);
1073 const auto *DElt = DConst->getAggregateElement(
I);
1074 const auto *EElt = EConst->getAggregateElement(
I);
1076 if (!BElt || !DElt || !EElt)
1078 if (!isReducible(BElt, DElt, EElt))
1083 if (!isReducible(
B,
D,
E))
1101 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *
E =
nullptr;
1106 std::optional<std::pair<unsigned, unsigned>> MaskPair =
1112 unsigned CmpMask0 = MaskPair->first;
1113 unsigned CmpMask1 = MaskPair->second;
1114 if ((CmpMask0 &
Mask_AllZeros) && (CmpMask1 == compareBMask)) {
1118 }
else if ((CmpMask0 == compareBMask) && (CmpMask1 &
Mask_AllZeros)) {
1129 Value *LHS1,
bool LHSOneUse,
1131 Value *RHS1,
bool RHSOneUse,
1140 else if (RHS1 == LHS0) {
1147 !(LHSOneUse || RHSOneUse))
1162 GetKnownNonZeroAndOther(
B,
A))
1163 return Builder.CreateICmpULT(Builder.CreateNeg(
B),
A);
1165 GetKnownNonZeroAndOther(
B,
A))
1166 return Builder.CreateICmpUGE(Builder.CreateNeg(
B),
A);
1181 return std::nullopt;
1183 unsigned NumOriginalBits =
X->getType()->getScalarSizeInBits();
1184 unsigned NumExtractedBits =
V->getType()->getScalarSizeInBits();
1190 Shift->
ule(NumOriginalBits - NumExtractedBits))
1192 return {{
X, 0, NumExtractedBits}};
1199 V = Builder.CreateLShr(
V,
P.StartBit);
1200 Type *TruncTy =
V->getType()->getWithNewBitWidth(
P.NumBits);
1201 if (TruncTy !=
V->getType())
1202 V = Builder.CreateTrunc(
V, TruncTy);
1209Value *InstCombinerImpl::foldEqOfParts(
Value *Cmp0,
Value *Cmp1,
bool IsAnd) {
1214 auto GetMatchPart = [&](
Value *CmpV,
1215 unsigned OpNo) -> std::optional<IntPart> {
1224 return {{OpNo == 0 ?
X :
Y, 0, 1}};
1228 return std::nullopt;
1230 if (
Pred ==
Cmp->getPredicate())
1239 return std::nullopt;
1248 return std::nullopt;
1250 return std::nullopt;
1255 return {{
I->getOperand(OpNo), From,
C->getBitWidth() - From}};
1258 std::optional<IntPart> L0 = GetMatchPart(Cmp0, 0);
1259 std::optional<IntPart> R0 = GetMatchPart(Cmp0, 1);
1260 std::optional<IntPart> L1 = GetMatchPart(Cmp1, 0);
1261 std::optional<IntPart> R1 = GetMatchPart(Cmp1, 1);
1262 if (!L0 || !R0 || !L1 || !R1)
1267 if (L0->From != L1->From || R0->From != R1->From) {
1268 if (L0->From != R1->From || R0->From != L1->From)
1275 if (L0->StartBit + L0->NumBits != L1->StartBit ||
1276 R0->StartBit + R0->NumBits != R1->StartBit) {
1277 if (L1->StartBit + L1->NumBits != L0->StartBit ||
1278 R1->StartBit + R1->NumBits != R0->StartBit)
1285 IntPart
L = {L0->From, L0->StartBit, L0->NumBits + L1->NumBits};
1286 IntPart
R = {R0->From, R0->StartBit, R0->NumBits + R1->NumBits};
1298 Value *RHS1,
bool RHSOneUse,
bool IsAnd,
1318 }
else if (LHS0 == RHS1)
1329 if (!SubstituteCmp) {
1334 SubstituteCmp = Builder.CreateICmp(PredR,
Y, LHS1);
1338 return IsAnd ? Builder.CreateLogicalAnd(
LHS, SubstituteCmp,
"", MDFrom)
1339 : Builder.CreateLogicalOr(
LHS, SubstituteCmp,
"", MDFrom);
1341 return Builder.CreateBinOp(IsAnd ? Instruction::And : Instruction::Or,
LHS,
1349Value *InstCombinerImpl::foldAndOrOfICmpsUsingRanges(
1353 auto MatchExactRangeCheck =
1355 Value *
RHS) -> std::optional<std::pair<Value *, ConstantRange>> {
1358 return std::nullopt;
1365 C->countr_zero() >=
Mask->countr_zero()) {
1366 ConstantRange CR(*
C, *
C - *Mask);
1369 return std::make_pair(
X, CR);
1377 return std::make_pair(
LHS, CR);
1380 auto RC1 = MatchExactRangeCheck(PredL, LHS0, LHS1);
1384 auto RC2 = MatchExactRangeCheck(PredR, RHS0, RHS1);
1388 auto &[
V1, CR1] = *RC1;
1389 auto &[V2, CR2] = *RC2;
1395 CR1 = CR1.inverse();
1396 CR2 = CR2.inverse();
1399 Type *Ty =
V1->getType();
1403 if (!LHSOneUse || !RHSOneUse || CR1.isWrappedSet() || CR2.isWrappedSet())
1408 APInt LowerDiff = CR1.getLower() ^ CR2.getLower();
1409 APInt UpperDiff = (CR1.getUpper() - 1) ^ (CR2.getUpper() - 1);
1410 APInt CR1Size = CR1.getUpper() - CR1.getLower();
1411 if (!LowerDiff.
isPowerOf2() || LowerDiff != UpperDiff ||
1412 CR1Size != CR2.getUpper() - CR2.getLower())
1415 CR = CR1.getLower().ult(CR2.getLower()) ? CR1 : CR2;
1416 NewV =
Builder.CreateAnd(NewV, ConstantInt::get(Ty, ~LowerDiff));
1424 CR->getEquivalentICmp(NewPred, NewC,
Offset);
1427 NewV =
Builder.CreateAdd(NewV, ConstantInt::get(Ty,
Offset));
1428 return Builder.CreateICmp(NewPred, NewV, ConstantInt::get(Ty, NewC));
1447 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1448 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1460 bool IsAnd,
bool IsLogicalSelect) {
1461 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1462 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1465 if (LHS0 == RHS1 && RHS0 == LHS1) {
1485 if (LHS0 == RHS0 && LHS1 == RHS1) {
1488 unsigned NewPred = IsAnd ? FCmpCodeL & FCmpCodeR : FCmpCodeL | FCmpCodeR;
1508 FastMathFlags FMF =
LHS->getFastMathFlags() &
RHS->getFastMathFlags();
1509 if (IsLogicalSelect) {
1510 Y =
Builder.CreateFreeze(
Y,
Y->getName() +
".fr");
1514 return Builder.CreateFCmpFMF(PredL, LHS0,
Y, FMF);
1519 if (!IsLogicalSelect && IsAnd &&
1535 auto [ClassValRHS, ClassMaskRHS] =
1538 auto [ClassValLHS, ClassMaskLHS] =
1540 if (ClassValLHS == ClassValRHS) {
1541 unsigned CombinedMask = IsAnd ? (ClassMaskLHS & ClassMaskRHS)
1542 : (ClassMaskLHS | ClassMaskRHS);
1543 return Builder.CreateIntrinsic(
1544 Intrinsic::is_fpclass, {ClassValLHS->getType()},
1545 {ClassValLHS,
Builder.getInt32(CombinedMask)});
1573 if (IsLessThanOrLessEqual(IsAnd ? PredR : PredL)) {
1577 if (IsLessThanOrLessEqual(IsAnd ? PredL : PredR)) {
1578 FastMathFlags NewFlag =
LHS->getFastMathFlags();
1579 if (!IsLogicalSelect)
1580 NewFlag |=
RHS->getFastMathFlags();
1584 PredL, FAbs, ConstantFP::get(LHS0->
getType(), *LHSC), NewFlag);
1596 if (!FCmp || !FCmp->hasOneUse())
1599 std::tie(ClassVal, ClassMask) =
1600 fcmpToClassTest(FCmp->getPredicate(), *FCmp->getParent()->getParent(),
1601 FCmp->getOperand(0), FCmp->getOperand(1));
1602 return ClassVal !=
nullptr;
1613 Value *ClassVal0 =
nullptr;
1614 Value *ClassVal1 =
nullptr;
1631 ClassVal0 == ClassVal1) {
1632 unsigned NewClassMask;
1634 case Instruction::And:
1635 NewClassMask = ClassMask0 & ClassMask1;
1637 case Instruction::Or:
1638 NewClassMask = ClassMask0 | ClassMask1;
1640 case Instruction::Xor:
1641 NewClassMask = ClassMask0 ^ ClassMask1;
1650 1, ConstantInt::get(
II->getArgOperand(1)->getType(), NewClassMask));
1657 1, ConstantInt::get(
II->getArgOperand(1)->getType(), NewClassMask));
1662 Builder.CreateIntrinsic(Intrinsic::is_fpclass, {ClassVal0->
getType()},
1663 {ClassVal0,
Builder.getInt32(NewClassMask)});
1677Instruction *InstCombinerImpl::canonicalizeConditionalNegationViaMathToSelect(
1679 assert(
I.getOpcode() == BinaryOperator::Xor &&
"Only for xor!");
1684 !
Cond->getType()->isIntOrIntVectorTy(1) ||
1687 return createSelectInstWithUnknownProfile(
1698 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1699 "Expecting and/or op for fcmp transform");
1718 X->getType() !=
Y->getType())
1722 X->getType() !=
Y->getType())
1739 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1740 "Trying to match De Morgan's Laws with something other than and/or");
1744 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1746 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1772bool InstCombinerImpl::shouldOptimizeCast(
CastInst *CI) {
1782 if (isEliminableCastPair(PrecedingCI, CI))
1810 auto *ZExt =
new ZExtInst(NewOp, DestTy);
1811 ZExt->setNonNeg(Flags.NNeg);
1812 ZExt->andIRFlags(Cast);
1821 return new SExtInst(NewOp, DestTy);
1831 assert(
I.isBitwiseLogicOp() &&
"Unexpected opcode for bitwise logic folding");
1833 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1839 auto FoldBitwiseICmpZeroWithICmp = [&](
Value *Op0,
1840 Value *Op1) -> Instruction * {
1855 auto *BitwiseOp =
Builder.CreateBinOp(LogicOpc, ICmpL, ICmpR);
1857 return new ZExtInst(BitwiseOp, Op0->
getType());
1860 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op0, Op1))
1863 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op1, Op0))
1872 Type *DestTy =
I.getType();
1898 unsigned XNumBits =
X->getType()->getScalarSizeInBits();
1899 unsigned YNumBits =
Y->getType()->getScalarSizeInBits();
1900 if (XNumBits != YNumBits) {
1908 if (XNumBits < YNumBits) {
1909 X =
Builder.CreateCast(CastOpcode,
X,
Y->getType());
1910 }
else if (YNumBits < XNumBits) {
1911 Y =
Builder.CreateCast(CastOpcode,
Y,
X->getType());
1916 Value *NarrowLogic =
Builder.CreateBinOp(LogicOpc,
X,
Y,
I.getName());
1919 if (Disjoint && NewDisjoint)
1920 NewDisjoint->setIsDisjoint(Disjoint->isDisjoint());
1932 if (shouldOptimizeCast(Cast0) && shouldOptimizeCast(Cast1)) {
1933 Value *NewOp =
Builder.CreateBinOp(LogicOpc, Cast0Src, Cast1Src,
1939 NewTrunc->setHasNoUnsignedWrap(
1940 LogicOpc == Instruction::And
1941 ? Trunc0->hasNoUnsignedWrap() || Trunc1->hasNoUnsignedWrap()
1942 : Trunc0->hasNoUnsignedWrap() && Trunc1->hasNoUnsignedWrap());
1943 NewTrunc->setHasNoSignedWrap(Trunc0->hasNoSignedWrap() &&
1944 Trunc1->hasNoSignedWrap());
1954 assert(
I.getOpcode() == Instruction::And);
1955 Value *Op0 =
I.getOperand(0);
1956 Value *Op1 =
I.getOperand(1);
1964 return BinaryOperator::CreateXor(
A,
B);
1980 assert(
I.getOpcode() == Instruction::Or);
1981 Value *Op0 =
I.getOperand(0);
1982 Value *Op1 =
I.getOperand(1);
2007 return BinaryOperator::CreateXor(
A,
B);
2027 Value *Op0 =
And.getOperand(0), *Op1 =
And.getOperand(1);
2048 if (
Opc == Instruction::LShr ||
Opc == Instruction::Shl)
2057 return new ZExtInst(
Builder.CreateAnd(NewBO,
X), Ty);
2065 assert(Opcode == Instruction::And || Opcode == Instruction::Or);
2069 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
2071 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2078 const auto matchNotOrAnd =
2079 [Opcode, FlippedOpcode](
Value *
Op,
auto m_A,
auto m_B,
auto m_C,
2080 Value *&
X,
bool CountUses =
false) ->
bool {
2081 if (CountUses && !
Op->hasOneUse())
2087 return !CountUses ||
X->hasOneUse();
2103 return (Opcode == Instruction::Or)
2104 ? BinaryOperator::CreateAnd(
Xor, Builder.CreateNot(
A))
2113 return (Opcode == Instruction::Or)
2114 ? BinaryOperator::CreateAnd(
Xor, Builder.CreateNot(
B))
2123 Opcode, Builder.CreateBinOp(FlippedOpcode,
B,
C),
A));
2130 Opcode, Builder.CreateBinOp(FlippedOpcode,
A,
C),
B));
2136 if (Opcode == Instruction::Or && Op0->
hasOneUse() &&
2174 return (Opcode == Instruction::Or)
2176 : BinaryOperator::CreateOr(
Xor,
X);
2184 FlippedOpcode, Builder.CreateBinOp(Opcode,
C, Builder.CreateNot(
B)),
2192 FlippedOpcode, Builder.CreateBinOp(Opcode,
B, Builder.CreateNot(
C)),
2212 if (!
X->hasOneUse()) {
2213 Value *YZ = Builder.CreateBinOp(Opcode,
Y, Z);
2217 if (!
Y->hasOneUse()) {
2218 Value *XZ = Builder.CreateBinOp(Opcode,
X, Z);
2238 Type *Ty =
I.getType();
2240 Value *Op0 =
I.getOperand(0);
2241 Value *Op1 =
I.getOperand(1);
2249 unsigned Width = Ty->getScalarSizeInBits();
2253 case Instruction::And:
2254 if (
C->countl_one() < LastOneMath)
2257 case Instruction::Xor:
2258 case Instruction::Or:
2259 if (
C->countl_zero() < LastOneMath)
2266 Value *NewBinOp = Builder.CreateBinOp(OpC,
X, ConstantInt::get(Ty, *
C));
2268 ConstantInt::get(Ty, *C2), Op0);
2275 assert((
I.isBitwiseLogicOp() ||
I.getOpcode() == Instruction::Add) &&
2276 "Unexpected opcode");
2279 Constant *ShiftedC1, *ShiftedC2, *AddC;
2280 Type *Ty =
I.getType();
2296 if (!Op0Inst || !Op1Inst)
2302 if (ShiftOp != Op1Inst->getOpcode())
2306 if (
I.getOpcode() == Instruction::Add && ShiftOp != Instruction::Shl)
2310 I.getOpcode(), ShiftedC1,
Builder.CreateBinOp(ShiftOp, ShiftedC2, AddC));
2326 assert(
I.isBitwiseLogicOp() &&
"Should and/or/xor");
2327 if (!
I.getOperand(0)->hasOneUse())
2334 if (
Y && (!
Y->hasOneUse() ||
X->getIntrinsicID() !=
Y->getIntrinsicID()))
2340 if (!
Y && (!(IID == Intrinsic::bswap || IID == Intrinsic::bitreverse) ||
2345 case Intrinsic::fshl:
2346 case Intrinsic::fshr: {
2347 if (
X->getOperand(2) !=
Y->getOperand(2))
2350 Builder.CreateBinOp(
I.getOpcode(),
X->getOperand(0),
Y->getOperand(0));
2352 Builder.CreateBinOp(
I.getOpcode(),
X->getOperand(1),
Y->getOperand(1));
2357 case Intrinsic::bswap:
2358 case Intrinsic::bitreverse: {
2359 Value *NewOp0 = Builder.CreateBinOp(
2360 I.getOpcode(),
X->getOperand(0),
2361 Y ?
Y->getOperand(0)
2362 : ConstantInt::get(
I.getType(), IID == Intrinsic::bswap
2382 unsigned Depth = 0) {
2390 if (!
I || !
I->isBitwiseLogicOp() ||
Depth >= 3)
2393 if (!
I->hasOneUse())
2394 SimplifyOnly =
true;
2397 SimplifyOnly, IC,
Depth + 1);
2399 SimplifyOnly, IC,
Depth + 1);
2400 if (!NewOp0 && !NewOp1)
2404 NewOp0 =
I->getOperand(0);
2406 NewOp1 =
I->getOperand(1);
2429 APInt Mask = ~*NegP;
2445 Type *Ty =
I.getType();
2446 Value *NewAdd = Builder.CreateAdd(
X, ConstantInt::get(Ty, Mask));
2447 return BinaryOperator::CreateAnd(NewAdd, ConstantInt::get(Ty, *NegP));
2455 bool RHSIsLogical) {
2460 if (
Value *Res = foldBooleanAndOr(
LHS,
X,
I, IsAnd,
false))
2462 :
Builder.CreateBinOp(Opcode, Res,
Y);
2465 else if (
Value *Res = foldBooleanAndOr(
LHS,
Y,
I, IsAnd,
false))
2467 :
Builder.CreateBinOp(Opcode,
X, Res);
2484 Type *Ty =
I.getType();
2487 SQ.getWithInstruction(&
I)))
2518 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2527 Value *IsZero =
Builder.CreateICmpEQ(
X, ConstantInt::get(Ty, 0));
2537 return createSelectInstWithUnknownProfile(Cmp,
2547 return BinaryOperator::CreateAnd(
Builder.CreateNot(
X),
Y);
2553 Constant *NewC = ConstantInt::get(Ty, *
C & *XorC);
2556 return BinaryOperator::CreateXor(
And, NewC);
2567 APInt Together = *
C & *OrC;
2570 return BinaryOperator::CreateOr(
And, ConstantInt::get(Ty, Together));
2573 unsigned Width = Ty->getScalarSizeInBits();
2574 const APInt *ShiftC;
2576 ShiftC->
ult(Width)) {
2581 Constant *ShAmtC = ConstantInt::get(Ty, ShiftC->
zext(Width));
2582 return BinaryOperator::CreateLShr(Sext, ShAmtC);
2590 return BinaryOperator::CreateLShr(
X, ConstantInt::get(Ty, *ShiftC));
2598 if (Op0->
hasOneUse() &&
C->isPowerOf2() && (*AddC & (*
C - 1)) == 0) {
2599 assert((*
C & *AddC) != 0 &&
"Expected common bit");
2601 return BinaryOperator::CreateXor(NewAnd, Op1);
2608 switch (
B->getOpcode()) {
2609 case Instruction::Xor:
2610 case Instruction::Or:
2611 case Instruction::Mul:
2612 case Instruction::Add:
2613 case Instruction::Sub:
2629 C->isIntN(
X->getType()->getScalarSizeInBits())) {
2630 unsigned XWidth =
X->getType()->getScalarSizeInBits();
2631 Constant *TruncC1 = ConstantInt::get(
X->getType(),
C1->trunc(XWidth));
2633 ?
Builder.CreateBinOp(BOpcode,
X, TruncC1)
2634 :
Builder.CreateBinOp(BOpcode, TruncC1,
X);
2635 Constant *TruncC = ConstantInt::get(
X->getType(),
C->trunc(XWidth));
2645 C->isMask(
X->getType()->getScalarSizeInBits())) {
2647 Value *TrY =
Builder.CreateTrunc(
Y,
X->getType(),
Y->getName() +
".tr");
2655 C->isMask(
X->getType()->getScalarSizeInBits())) {
2657 Value *TrY =
Builder.CreateTrunc(
Y,
X->getType(),
Y->getName() +
".tr");
2674 Value *NewRHS =
Builder.CreateAnd(
Y, Op1,
Y->getName() +
".masked");
2680 Value *NewLHS =
Builder.CreateAnd(
X, Op1,
X->getName() +
".masked");
2689 if (
C->isPowerOf2() &&
2692 int Log2C =
C->exactLogBase2();
2695 int BitNum = IsShiftLeft ? Log2C - Log2ShiftC : Log2ShiftC - Log2C;
2696 assert(BitNum >= 0 &&
"Expected demanded bits to handle impossible mask");
2697 Value *Cmp =
Builder.CreateICmpEQ(
X, ConstantInt::get(Ty, BitNum));
2698 return createSelectInstWithUnknownProfile(Cmp, ConstantInt::get(Ty, *
C),
2718 return createSelectInstWithUnknownProfile(
2729 if (Cmp && Cmp->isNullValue()) {
2735 return createSelectInstWithUnknownProfile(
2751 const APInt *ShAmtC;
2759 ShAmtC->
ult(Width)) {
2760 unsigned S =
C->popcount();
2762 bool IsAShr = Shr->
getOpcode() == Instruction::AShr;
2763 if (S <= ShAmt && (IsAShr || ShAmt + S <= Width) &&
2766 I,
Builder.CreateBinaryIntrinsic(Intrinsic::umin,
X, Op1));
2781 !
Builder.GetInsertBlock()->getParent()->hasFnAttribute(
2782 Attribute::NoImplicitFloat)) {
2797 APInt(Ty->getScalarSizeInBits(),
2798 Ty->getScalarSizeInBits() -
2799 X->getType()->getScalarSizeInBits())))) {
2800 auto *SExt =
Builder.CreateSExt(
X, Ty,
X->getName() +
".signext");
2801 return BinaryOperator::CreateAnd(SExt, Op1);
2807 if (
I.getType()->isIntOrIntVectorTy(1)) {
2810 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
true))
2815 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
true))
2830 return BinaryOperator::CreateAnd(Op0,
B);
2833 return BinaryOperator::CreateAnd(Op1,
B);
2841 if (NotC !=
nullptr)
2842 return BinaryOperator::CreateAnd(Op0, NotC);
2851 if (NotC !=
nullptr)
2852 return BinaryOperator::CreateAnd(Op1, NotC);
2861 return BinaryOperator::CreateAnd(
A,
B);
2869 return BinaryOperator::CreateAnd(
A,
B);
2877 return BinaryOperator::CreateAnd(
Builder.CreateNot(
A),
B);
2885 return BinaryOperator::CreateAnd(
Builder.CreateNot(
A),
B);
2889 foldBooleanAndOr(Op0, Op1,
I,
true,
false))
2894 if (
auto *V = reassociateBooleanAndOr(Op0,
X,
Y,
I,
true,
2900 if (
auto *V = reassociateBooleanAndOr(Op1,
X,
Y,
I,
true,
2908 if (
Instruction *CastedAnd = foldCastedBitwiseLogic(
I))
2921 A->getType()->isIntOrIntVectorTy(1))
2927 A->getType()->isIntOrIntVectorTy(1))
2932 A->getType()->isIntOrIntVectorTy(1))
2933 return createSelectInstWithUnknownProfile(
2934 A,
Builder.CreateAnd(
B, ConstantInt::get(Ty, 1)),
2940 if (
A->getType()->isIntOrIntVectorTy(1))
2944 return createSelectInstWithUnknownProfile(
2954 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2956 return createSelectInstWithUnknownProfile(IsNeg,
Y,
2964 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2966 return createSelectInstWithUnknownProfile(IsNeg,
2976 Value *Start =
nullptr, *Step =
nullptr;
2984 return Canonicalized;
2998 return BinaryOperator::CreateAnd(V, Op1);
3002 return BinaryOperator::CreateAnd(Op0, V);
3012 bool MatchBitReversals) {
3020 for (
auto *Inst : Insts) {
3021 Inst->setDebugLoc(
I.getDebugLoc());
3027std::optional<std::pair<Intrinsic::ID, SmallVector<Value *, 3>>>
3031 assert(
Or.getOpcode() == BinaryOperator::Or &&
"Expecting or instruction");
3033 unsigned Width =
Or.getType()->getScalarSizeInBits();
3038 return std::nullopt;
3046 Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
3052 return std::nullopt;
3055 if (Or0->
getOpcode() == BinaryOperator::LShr) {
3061 Or1->
getOpcode() == BinaryOperator::LShr &&
3062 "Illegal or(shift,shift) pair");
3066 auto matchShiftAmount = [&](
Value *L,
Value *R,
unsigned Width) ->
Value * {
3068 const APInt *LI, *RI;
3070 if (LI->
ult(Width) && RI->
ult(Width) && (*LI + *RI) == Width)
3071 return ConstantInt::get(L->getType(), *LI);
3095 if (ShVal0 != ShVal1)
3106 unsigned Mask = Width - 1;
3114 Value *XPlusOne =
nullptr;
3141 Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, Width);
3143 ShAmt = matchShiftAmount(ShAmt1, ShAmt0, Width);
3147 return std::nullopt;
3149 FShiftArgs = {ShVal0, ShVal1, ShAmt};
3166 const APInt *ZextHighShlAmt;
3169 return std::nullopt;
3173 return std::nullopt;
3175 unsigned HighSize =
High->getType()->getScalarSizeInBits();
3176 unsigned LowSize =
Low->getType()->getScalarSizeInBits();
3179 if (ZextHighShlAmt->
ult(LowSize) || ZextHighShlAmt->
ugt(Width - HighSize))
3180 return std::nullopt;
3190 const APInt *ZextLowShlAmt;
3197 if (*ZextLowShlAmt + *ZextHighShlAmt != Width)
3203 ZextLowShlAmt->
ule(Width - LowSize) &&
"Invalid concat");
3212 FShiftArgs = {U, U, ConstantInt::get(Or0->
getType(), *ZextHighShlAmt)};
3217 if (FShiftArgs.
empty())
3218 return std::nullopt;
3220 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
3221 return std::make_pair(IID, FShiftArgs);
3227 auto [IID, FShiftArgs] = *Opt;
3238 assert(
Or.getOpcode() == Instruction::Or &&
"bswap requires an 'or'");
3239 Value *Op0 =
Or.getOperand(0), *Op1 =
Or.getOperand(1);
3242 unsigned Width = Ty->getScalarSizeInBits();
3243 if ((Width & 1) != 0)
3245 unsigned HalfWidth = Width / 2;
3252 Value *LowerSrc, *ShlVal, *UpperSrc;
3263 Value *NewLower = Builder.CreateZExt(
Lo, Ty);
3264 Value *NewUpper = Builder.CreateZExt(
Hi, Ty);
3265 NewUpper = Builder.CreateShl(NewUpper, HalfWidth);
3266 Value *BinOp = Builder.CreateDisjointOr(NewLower, NewUpper);
3267 return Builder.CreateIntrinsic(
id, Ty, BinOp);
3272 Value *LowerBSwap, *UpperBSwap;
3275 return ConcatIntrinsicCalls(Intrinsic::bswap, UpperBSwap, LowerBSwap);
3279 Value *LowerBRev, *UpperBRev;
3282 return ConcatIntrinsicCalls(Intrinsic::bitreverse, UpperBRev, LowerBRev);
3294 return Builder.CreateSExt(
X, Ty);
3302 for (
unsigned i = 0; i != NumElts; ++i) {
3303 Constant *EltC1 =
C1->getAggregateElement(i);
3305 if (!EltC1 || !EltC2)
3324 Type *Ty =
A->getType();
3340 if (
A->getType()->isIntOrIntVectorTy()) {
3342 if (NumSignBits ==
A->getType()->getScalarSizeInBits() &&
3365 Cond->getType()->isIntOrIntVectorTy(1)) {
3391 Cond->getType()->isIntOrIntVectorTy(1) &&
3405 Value *
D,
bool InvertFalseVal) {
3411 if (
Value *
Cond = getSelectCondition(
A,
C, InvertFalseVal)) {
3416 Type *SelTy =
A->getType();
3419 unsigned Elts = VecTy->getElementCount().getKnownMinValue();
3423 Type *EltTy =
Builder.getIntNTy(SelEltSize / Elts);
3444 Value *LHS1,
bool LHSOneUse,
3446 Value *RHS1,
bool RHSOneUse,
3447 bool IsAnd,
bool IsLogical,
3459 auto MatchRHSOp = [LHS0, CInt](
const Value *RHSOp) {
3462 (CInt->
isZero() && RHSOp == LHS0);
3476 return Builder.CreateICmp(
3478 Builder.CreateSub(LHS0, ConstantInt::get(LHS0->
getType(), *CInt + 1)),
3488 CmpPredicate PredL, PredR;
3489 Value *LHS0, *LHS1, *RHS0, *RHS1;
3497 const SimplifyQuery Q =
SQ.getWithInstruction(&
I);
3499 const APInt *LHSC =
nullptr, *RHSC =
nullptr;
3506 if (LHS0 == RHS1 && LHS1 == RHS0) {
3510 if (LHS0 == RHS0 && LHS1 == RHS1) {
3519 PredR, RHS0, RHS1, RHSOneUse,
3525 PredR, RHS0, RHS1, RHSOneUse, PredL, LHS0, LHS1, LHSOneUse, IsAnd,
3530 RHS0, RHS1, RHSOneUse, IsAnd,
3539 PredR, RHS0, RHS1,
RHS, PredL, LHS0, LHS1, LHSOneUse, IsAnd,
3544 CmpR->setSameSign(
false);
3574 if (IsAnd && !IsLogical)
3589 PredR, RHS0, RHS1, RHSOneUse,
3593 PredL, LHS0, LHS1, LHSOneUse,
3607 return Builder.CreateICmp(PredL, NewOr,
3619 return Builder.CreateICmp(PredL, NewAnd,
3625 Builder, PredL, LHS0, LHS1, LHSOneUse, PredR, RHS0, RHS1, RHSOneUse,
3638 bool TrueIfSignedL, TrueIfSignedR;
3644 if ((TrueIfSignedL && !TrueIfSignedR &&
3647 (!TrueIfSignedL && TrueIfSignedR &&
3651 return Builder.CreateIsNeg(NewXor);
3654 if ((TrueIfSignedL && !TrueIfSignedR &&
3657 (!TrueIfSignedL && TrueIfSignedR &&
3661 return Builder.CreateIsNotNeg(NewXor);
3672 !
I.getFunction()->hasFnAttribute(Attribute::NoImplicitFloat) &&
3673 LHSOneUse && RHSOneUse &&
3675 X->getType()->getScalarType()->isIEEELikeFPTy() &&
3676 APFloat(
X->getType()->getScalarType()->getFltSemantics(), *MaskC)
3678 ((LHSC->
isZero() && *RHSC == *MaskC) ||
3679 (RHSC->
isZero() && *LHSC == *MaskC)))
3683 return foldAndOrOfICmpsUsingRanges(PredL, LHS0, LHS1, LHSOneUse, PredR, RHS0,
3684 RHS1, RHSOneUse, IsAnd);
3699 SQ.getWithInstruction(&
I)))
3702 if (
Value *Res = foldAndOrOfICmps(
LHS,
RHS,
I, IsAnd, IsLogical))
3707 if (
Value *Res = foldLogicOfFCmps(LHSCmp, RHSCmp, IsAnd, IsLogical))
3718 assert(
I.getOpcode() == Instruction::Or &&
3719 "Simplification only supports or at the moment.");
3721 Value *Cmp1, *Cmp2, *Cmp3, *Cmp4;
3728 return Builder.CreateXor(Cmp1, Cmp4);
3730 return Builder.CreateXor(Cmp1, Cmp3);
3760 const unsigned EltBitWidth = EltTy->getBitWidth();
3761 const unsigned TargetBitWidth =
V->getType()->getIntegerBitWidth();
3762 if (TargetBitWidth % EltBitWidth != 0 || ShlAmt % EltBitWidth != 0)
3764 const unsigned TargetEltWidth = TargetBitWidth / EltBitWidth;
3765 const unsigned ShlEltAmt = ShlAmt / EltBitWidth;
3767 const unsigned MaskIdx =
3768 DL.isLittleEndian() ? ShlEltAmt : TargetEltWidth - ShlEltAmt - 1;
3770 VecOffset =
static_cast<int64_t
>(VecIdx) -
static_cast<int64_t
>(MaskIdx);
3771 Mask.resize(TargetEltWidth);
3785 Mask.resize(SrcTy->getNumElements());
3799 const unsigned NumVecElts = VecTy->getNumElements();
3800 bool FoundVecOffset =
false;
3801 for (
unsigned Idx = 0; Idx < ShuffleMask.size(); ++Idx) {
3804 const unsigned ShuffleIdx = ShuffleMask[Idx];
3805 if (ShuffleIdx >= NumVecElts) {
3806 const unsigned ConstIdx = ShuffleIdx - NumVecElts;
3809 if (!ConstElt || !ConstElt->isNullValue())
3814 if (FoundVecOffset) {
3815 if (VecOffset + Idx != ShuffleIdx)
3818 if (ShuffleIdx < Idx)
3820 VecOffset = ShuffleIdx - Idx;
3821 FoundVecOffset =
true;
3825 return FoundVecOffset;
3838 bool AlreadyInsertedMaskedElt = Mask.test(InsertIdx);
3840 if (!AlreadyInsertedMaskedElt)
3841 Mask.reset(InsertIdx);
3850 assert(
I.getOpcode() == Instruction::Or);
3851 Value *LhsVec, *RhsVec;
3852 int64_t LhsVecOffset, RhsVecOffset;
3860 if (LhsVec != RhsVec || LhsVecOffset != RhsVecOffset)
3864 const unsigned ZeroVecIdx =
3867 for (
unsigned Idx : Mask.set_bits()) {
3868 assert(LhsVecOffset + Idx >= 0);
3869 ShuffleMask[Idx] = LhsVecOffset + Idx;
3872 Value *MaskedVec = Builder.CreateShuffleVector(
3874 I.getName() +
".v");
3900 const APInt *ShiftedMaskConst =
nullptr;
3907 if (!
match(MaskedOp0,
3912 if (LShrAmt > ShlAmt)
3914 Offset = ShlAmt - LShrAmt;
3916 Mask = ShiftedMaskConst ? ShiftedMaskConst->
shl(LShrAmt)
3918 Int->getType()->getScalarSizeInBits(), LShrAmt);
3928 Value *LhsInt, *RhsInt;
3929 APInt LhsMask, RhsMask;
3931 bool IsLhsShlNUW, IsLhsShlNSW, IsRhsShlNUW, IsRhsShlNSW;
3938 if (LhsInt != RhsInt || LhsOffset != RhsOffset)
3941 APInt Mask = LhsMask | RhsMask;
3944 Value *Res = Builder.CreateShl(
3946 Builder.CreateAnd(LhsInt, Mask, LhsInt->
getName() +
".mask"), DestTy,
3948 ConstantInt::get(DestTy, LhsOffset),
"", IsLhsShlNUW && IsRhsShlNUW,
3949 IsLhsShlNSW && IsRhsShlNSW);
3974 return std::nullopt;
3977 Value *Original =
nullptr;
3978 const APInt *Mask =
nullptr;
3979 const APInt *MulConst =
nullptr;
3982 if (MulConst->
isZero() || Mask->isZero())
3983 return std::nullopt;
3985 return std::optional<DecomposedBitMaskMul>(
3986 {Original, *MulConst, *Mask,
3992 const APInt *EqZero =
nullptr, *NeZero =
nullptr;
3996 auto ICmpDecompose =
3999 if (!ICmpDecompose.has_value())
4000 return std::nullopt;
4004 if (ICmpDecompose->X->getType() !=
V->getType())
4005 return std::nullopt;
4008 ICmpDecompose->C.isZero());
4013 if (!EqZero->
isZero() || NeZero->isZero())
4014 return std::nullopt;
4016 if (!ICmpDecompose->Mask.isPowerOf2() || ICmpDecompose->Mask.isZero())
4017 return std::nullopt;
4019 if (!NeZero->urem(ICmpDecompose->Mask).isZero())
4020 return std::nullopt;
4022 return std::optional<DecomposedBitMaskMul>(
4023 {ICmpDecompose->X, NeZero->udiv(ICmpDecompose->Mask),
4024 ICmpDecompose->Mask,
false,
false});
4027 return std::nullopt;
4043 if (Decomp0->isCombineableWith(*Decomp1)) {
4044 Value *NewAnd = Builder.CreateAnd(
4046 ConstantInt::get(Decomp0->X->getType(), Decomp0->Mask + Decomp1->Mask));
4048 return Builder.CreateMul(
4049 NewAnd, ConstantInt::get(NewAnd->
getType(), Decomp1->Factor),
"",
4050 Decomp0->NUW && Decomp1->NUW, Decomp0->NSW && Decomp1->NSW);
4069 if (
Value *Res = foldDisjointOr(
LHS,
X))
4070 return Builder.CreateDisjointOr(Res,
Y);
4071 if (
Value *Res = foldDisjointOr(
LHS,
Y))
4072 return Builder.CreateDisjointOr(Res,
X);
4076 if (
Value *Res = foldDisjointOr(
X,
RHS))
4077 return Builder.CreateDisjointOr(Res,
Y);
4078 if (
Value *Res = foldDisjointOr(
Y,
RHS))
4079 return Builder.CreateDisjointOr(Res,
X);
4123 return Builder.CreateBinaryIntrinsic(Intrinsic::abs,
X,
4124 Builder.getFalse());
4142 bool MayNeedFreeze = SelOp0 && SelOp1 &&
4143 match(SelOp1->getTrueValue(),
4148 Value *C2 =
nullptr, *A2 =
nullptr, *B2 =
nullptr;
4157 return createSelectInstWithUnknownProfile(
C,
A,
B);
4173 bool MayNeedFreeze = SelOp0 && SelOp1 &&
4174 match(SelOp0->getTrueValue(),
4179 Value *C2 =
nullptr, *A2 =
nullptr, *B2 =
nullptr;
4188 return createSelectInstWithUnknownProfile(
C,
B,
A);
4202 SQ.getWithInstruction(&
I)))
4238 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
4239 Type *Ty =
I.getType();
4240 if (Ty->isIntOrIntVectorTy(1)) {
4243 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
false))
4248 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
false))
4285 if (
Value *Res = foldDisjointOr(
I.getOperand(0),
I.getOperand(1)))
4288 if (
Value *Res = reassociateDisjointOr(
I.getOperand(0),
I.getOperand(1)))
4299 return BinaryOperator::CreateXor(
Or, ConstantInt::get(Ty, *CV));
4306 Value *IncrementY =
Builder.CreateAdd(
Y, ConstantInt::get(Ty, 1));
4307 return BinaryOperator::CreateMul(
X, IncrementY);
4324 if (
I.getType()->isIntOrIntVectorTy(1) &&
4343 return BinaryOperator::CreateOr(
Builder.CreateAnd(
X, *
C0),
B);
4346 return BinaryOperator::CreateOr(
Builder.CreateAnd(
X, *
C1),
A);
4350 return BinaryOperator::CreateXor(
Builder.CreateAnd(
X, *
C0),
B);
4353 return BinaryOperator::CreateXor(
Builder.CreateAnd(
X, *
C1),
A);
4362 return BinaryOperator::CreateAnd(
A, C01);
4369 return BinaryOperator::CreateAnd(
B, C01);
4373 const APInt *C2, *C3;
4379 return BinaryOperator::CreateAnd(
Or, C01);
4386 const APInt *ShiftAmt;
4389 ShiftAmt->
ult(
A->getType()->getScalarSizeInBits()) &&
4390 C1->isIntN(
A->getType()->getScalarSizeInBits() -
4392 return BinaryOperator::CreateAnd(
4393 A, ConstantInt::get(
I.getType(), *
C0 | *
C1));
4399 ShiftAmt->
ult(
A->getType()->getScalarSizeInBits()) &&
4400 C0->isIntN(
A->getType()->getScalarSizeInBits() -
4402 return BinaryOperator::CreateAnd(
4403 B, ConstantInt::get(
I.getType(), *
C0 | *
C1));
4412 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D))
4414 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B))
4416 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D))
4418 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B))
4420 if (
Value *V = matchSelectFromAndOr(
B,
D,
A,
C))
4422 if (
Value *V = matchSelectFromAndOr(
B,
D,
C,
A))
4424 if (
Value *V = matchSelectFromAndOr(
D,
B,
A,
C))
4426 if (
Value *V = matchSelectFromAndOr(
D,
B,
C,
A))
4435 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D,
true))
4437 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B,
true))
4439 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D,
true))
4441 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B,
true))
4450 return BinaryOperator::CreateOr(Op0,
C);
4457 return BinaryOperator::CreateOr(Op1,
C);
4463 bool SwappedForXor =
false;
4466 SwappedForXor =
true;
4473 return BinaryOperator::CreateOr(Op0,
B);
4475 return BinaryOperator::CreateOr(Op0,
A);
4480 return BinaryOperator::CreateOr(
A,
B);
4508 return BinaryOperator::CreateOr(Nand,
C);
4516 foldBooleanAndOr(Op0, Op1,
I,
false,
false))
4521 if (
auto *V = reassociateBooleanAndOr(Op0,
X,
Y,
I,
false,
4527 if (
auto *V = reassociateBooleanAndOr(Op1,
X,
Y,
I,
false,
4547 A->getType()->isIntOrIntVectorTy(1))
4548 return createSelectInstWithUnknownProfile(
4574 return IsDisjointOuter && IsDisjointInner
4575 ? BinaryOperator::CreateDisjointOr(Inner, CI)
4576 : BinaryOperator::CreateOr(Inner, CI);
4583 Value *
X =
nullptr, *
Y =
nullptr;
4602 return createSelectInstWithUnknownProfile(NewICmpInst,
AllOnes,
X);
4615 return BinaryOperator::CreateXor(
A,
B);
4631 Value *
Mul, *Ov, *MulIsNotZero, *UMulWithOv;
4649 return BinaryOperator::CreateAnd(NotNullA, NotNullB);
4677 return BinaryOperator::CreateOr(Ov, NewCmp);
4696 ConstantInt::get(Ty, Ty->getScalarSizeInBits() - 1),
X);
4702 Value *Start =
nullptr, *Step =
nullptr;
4720 return BinaryOperator::CreateOr(
4732 return BinaryOperator::CreateOr(
4740 return Canonicalized;
4762 !
Builder.GetInsertBlock()->getParent()->hasFnAttribute(
4763 Attribute::NoImplicitFloat)) {
4777 if ((KnownX.
One & *C2) == *C2)
4778 return BinaryOperator::CreateAnd(
X, ConstantInt::get(Ty, *
C1 | *C2));
4787 return BinaryOperator::CreateOr(V, Op1);
4791 return BinaryOperator::CreateOr(Op0, V);
4806 unsigned BitWidth = Ty->getScalarSizeInBits();
4813 I,
Builder.CreateIntrinsic(Ty, Intrinsic::scmp,
4814 {X, Constant::getNullValue(Ty)}));
4824 assert(
I.getOpcode() == Instruction::Xor);
4825 Value *Op0 =
I.getOperand(0);
4826 Value *Op1 =
I.getOperand(1);
4837 return BinaryOperator::CreateXor(
A,
B);
4845 return BinaryOperator::CreateXor(
A,
B);
4853 return BinaryOperator::CreateXor(
A,
B);
4875 assert(
I.getOpcode() == Instruction::Xor &&
I.getOperand(0) ==
LHS &&
4876 I.getOperand(1) ==
RHS &&
"Should be 'xor' with these operands");
4879 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
4880 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
4883 if (LHS0 == RHS1 && LHS1 == RHS0) {
4887 if (LHS0 == RHS0 && LHS1 == RHS1) {
4890 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
4895 const APInt *LC, *RC;
4904 bool TrueIfSignedL, TrueIfSignedR;
4909 return TrueIfSignedL == TrueIfSignedR ?
Builder.CreateIsNeg(XorLR) :
4910 Builder.CreateIsNotNeg(XorLR);
4920 if (CRUnion && CRIntersect)
4921 if (
auto CR = CRUnion->exactIntersectWith(CRIntersect->inverse())) {
4922 if (CR->isFullSet())
4924 if (CR->isEmptySet())
4929 CR->getEquivalentICmp(NewPred, NewC,
Offset);
4936 NewV =
Builder.CreateAdd(NewV, ConstantInt::get(Ty,
Offset));
4937 return Builder.CreateICmp(NewPred, NewV,
4938 ConstantInt::get(Ty, NewC));
4970 ICmpInst *
X =
nullptr, *
Y =
nullptr;
4971 if (OrICmp ==
LHS && AndICmp ==
RHS) {
4976 if (OrICmp ==
RHS && AndICmp ==
LHS) {
4983 Y->setPredicate(
Y->getInversePredicate());
4985 if (!
Y->hasOneUse()) {
4992 Builder.SetInsertPoint(++(
Y->getIterator()));
4996 Y->replaceUsesWithIf(NotY,
4997 [NotY](Use &U) {
return U.getUser() != NotY; });
5035 Value *NewA = Builder.CreateAnd(
D, NotM);
5036 return BinaryOperator::CreateXor(NewA,
X);
5042 Type *EltTy =
C->getType()->getScalarType();
5046 Value *NotC = Builder.CreateNot(
C);
5047 Value *
RHS = Builder.CreateAnd(
B, NotC);
5048 return BinaryOperator::CreateOr(
LHS,
RHS);
5063 return A ==
C ||
A ==
D ||
B ==
C ||
B ==
D;
5071 Value *NotY = Builder.CreateNot(
Y);
5072 return BinaryOperator::CreateOr(
X, NotY);
5079 Value *NotX = Builder.CreateNot(
X);
5080 return BinaryOperator::CreateOr(
Y, NotX);
5090 assert(
Xor.getOpcode() == Instruction::Xor &&
"Expected an xor instruction.");
5096 Value *Op0 =
Xor.getOperand(0), *Op1 =
Xor.getOperand(1);
5104 Op1->
hasNUses(2) && *ShAmt == Ty->getScalarSizeInBits() - 1 &&
5109 Value *IsNeg = Builder.CreateIsNeg(
A);
5112 Value *NegA =
Add->hasNoUnsignedWrap()
5114 : Builder.CreateNeg(
A,
"",
Add->hasNoSignedWrap());
5123 return I &&
I->getInsertionPointAfterDef() &&
5131 auto InsertPt =
I->getInsertionPointAfterDef();
5133 "freelyInvert requires an instruction with a valid insertion point");
5136 Op->replaceUsesWithIf(NotOp,
5137 [NotOp](
Use &U) {
return U.getUser() != NotOp; });
5178 auto InsertPt =
I.getInsertionPointAfterDef();
5179 assert(InsertPt &&
"sinkNotIntoLogicalOp requires an instruction with a "
5180 "valid insertion point");
5181 Builder.SetInsertPoint(*InsertPt);
5184 NewLogicOp =
Builder.CreateBinOp(NewOpc, Op0, Op1,
I.getName() +
".not");
5187 Builder.CreateLogicalOp(NewOpc, Op0, Op1,
I.getName() +
".not", &
I);
5189 SI->swapProfMetadata();
5213 Value *NotOp0 =
nullptr;
5214 Value *NotOp1 =
nullptr;
5215 Value **OpToInvert =
nullptr;
5238 Builder.SetInsertPoint(*
I.getInsertionPointAfterDef());
5241 NewBinOp =
Builder.CreateBinOp(NewOpc, Op0, Op1,
I.getName() +
".not");
5244 Builder.CreateLogicalOp(NewOpc, Op0, Op1,
I.getName() +
".not",
5247 NewSI->swapProfMetadata();
5271 Type *Ty =
I.getType();
5274 Value *NotY = Builder.CreateNot(
Y,
Y->getName() +
".not");
5275 return BinaryOperator::CreateOr(
X, NotY);
5278 Value *NotY = Builder.CreateNot(
Y,
Y->getName() +
".not");
5281 SI->swapProfMetadata();
5289 return BinaryOperator::CreateAnd(
X, NotY);
5295 SI->swapProfMetadata();
5300 BinaryOperator *NotVal;
5307 return BinaryOperator::CreateAnd(DecX, NotY);
5312 return BinaryOperator::CreateAShr(
X,
Y);
5318 return BinaryOperator::CreateAShr(
X,
Y);
5325 return new SExtInst(IsNotNeg, Ty);
5352 return BinaryOperator::CreateAdd(
Builder.CreateNot(
X),
Y);
5375 return new BitCastInst(
X, Ty);
5381 X->getType()->isIntOrIntVectorTy(1)) {
5385 return new BitCastInst(Sext, Ty);
5396 if (
II &&
II->hasOneUse()) {
5400 Value *InvMaxMin =
Builder.CreateBinaryIntrinsic(InvID,
X, NotY);
5404 if (
II->getIntrinsicID() == Intrinsic::is_fpclass) {
5407 1, ConstantInt::get(ClassMask->
getType(),
5423 Value *TV = Sel->getTrueValue();
5424 Value *FV = Sel->getFalseValue();
5427 bool InvertibleT = (CmpT && CmpT->hasOneUse()) ||
isa<Constant>(TV);
5428 bool InvertibleF = (CmpF && CmpF->hasOneUse()) ||
isa<Constant>(FV);
5429 if (InvertibleT && InvertibleF) {
5431 CmpT->setPredicate(CmpT->getInversePredicate());
5435 CmpF->setPredicate(CmpF->getInversePredicate());
5466 Value *NotC = Builder.CreateNot(AddC);
5469 return BinaryOperator::CreateAnd(NewSub, Mask);
5480 SQ.getWithInstruction(&
I)))
5510 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5518 return BinaryOperator::CreateXor(XorAC,
Y);
5521 return BinaryOperator::CreateXor(XorBC,
X);
5531 return BinaryOperator::CreateDisjointOr(Op0, Op1);
5533 return BinaryOperator::CreateOr(Op0, Op1);
5550 return BinaryOperator::CreateXor(
5573 *CA ==
X->getType()->getScalarSizeInBits() - 1 &&
5575 assert(!
C1->isNullValue() &&
"Unexpected xor with 0");
5577 return createSelectInstWithUnknownProfile(IsNotNeg, Op1,
5582 Type *Ty =
I.getType();
5590 return BinaryOperator::CreateSub(ConstantInt::get(Ty, *
C + *RHSC),
X);
5594 return BinaryOperator::CreateAdd(
X, ConstantInt::get(Ty, *
C + *RHSC));
5599 return BinaryOperator::CreateXor(
X, ConstantInt::get(Ty, *
C ^ *RHSC));
5607 *RHSC == Ty->getScalarSizeInBits() - 1) {
5609 if ((IID == Intrinsic::ctlz || IID == Intrinsic::cttz) &&
5612 IID = (IID == Intrinsic::ctlz) ? Intrinsic::cttz : Intrinsic::ctlz;
5625 return BinaryOperator::CreateShl(NotX, ConstantInt::get(Ty, *
C));
5631 return BinaryOperator::CreateLShr(NotX, ConstantInt::get(Ty, *
C));
5649 !
Builder.GetInsertBlock()->getParent()->hasFnAttribute(
5650 Attribute::NoImplicitFloat)) {
5673 auto *Opnd0 =
Builder.CreateLShr(
X, C2);
5674 Opnd0->takeName(Op0);
5675 return BinaryOperator::CreateXor(Opnd0, ConstantInt::get(Ty, FoldConst));
5688 return BinaryOperator::CreateAnd(
X,
Builder.CreateNot(Op0));
5692 return BinaryOperator::CreateAnd(
X,
Builder.CreateNot(Op1));
5697 return BinaryOperator::CreateAnd(Op0,
Builder.CreateNot(
X));
5705 return BinaryOperator::CreateAnd(Op1,
Builder.CreateNot(
X));
5711 return BinaryOperator::CreateXor(
5717 return BinaryOperator::CreateXor(
5723 return BinaryOperator::CreateOr(
A,
B);
5727 return BinaryOperator::CreateOr(
A,
B);
5737 return BinaryOperator::CreateOr(
A,
B);
5752 if (
B ==
C ||
B ==
D)
5758 return BinaryOperator::CreateAnd(
Builder.CreateXor(
B,
C), NotA);
5763 if (
I.getType()->isIntOrIntVectorTy(1) &&
5767 if (
B ==
C ||
B ==
D) {
5781 if (Op0SI->getCondition() ==
A)
5785 if (Op1SI->getCondition() ==
A)
5789 ? createSelectInstWithUnknownProfile(
A, NotB,
C)
5796 if (
Value *V = foldXorOfICmps(LHS, RHS,
I))
5799 if (
Instruction *CastedXor = foldCastedBitwiseLogic(
I))
5812 return BinaryOperator::CreateXor(
Builder.CreateXor(
X,
Y),
C1);
5818 return Canonicalized;
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 * 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 Value * foldLogOpOfMaskedICmpsAsymmetric(Value *LHS, Value *RHS, bool IsAnd, bool IsLogical, Value *A, Value *B, Value *C, Value *D, Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR, unsigned LHSMask, unsigned RHSMask, InstCombiner::BuilderTy &Builder)
Try to fold (icmp(A & B) ==/!= 0) &/| (icmp(A & D) ==/!= E) into a single (icmp(A & X) ==/!...
static Instruction * foldAndToXor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static unsigned getMaskedICmpType(Value *A, Value *B, Value *C, ICmpInst::Predicate Pred)
Return the set of patterns (from MaskedICmpType) that (icmp SCC (A & B), C) satisfies.
static Instruction * foldXorToXor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
A ^ B can be specified using other logic ops in a variety of patterns.
static bool canNarrowShiftAmt(Constant *C, unsigned BitWidth)
Return true if a constant shift amount is always less than the specified bit-width.
static 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 * foldSignedTruncationCheck(CmpPredicate PredL, Value *LHS0, Value *LHS1, CmpPredicate PredR, Value *RHS0, Value *RHS1, Instruction &CtxI, InstCombiner::BuilderTy &Builder)
General pattern: X & Y.
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 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 Value * getReconstructedMaskedICmp(IRBuilderBase &Builder, bool IsLogical, Value *RHS, Value *A, Value *D, Value *E, ICmpInst::Predicate PredR)
When foldLogOpOfMaskedICmps returns RHS for a logical and/or, we need to make sure that RHS is not mo...
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 Value * foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(Value *LHS, Value *RHS, bool IsAnd, bool IsLogical, 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 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 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.
MachineBasicBlock * Folded
SmallVector< MachineOperand, 4 > 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.
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.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
LLVM_ABI APInt sadd_ov(const APInt &RHS, bool &Overflow) const
bool intersects(const APInt &RHS) const
This operation tests if there are any pairs of corresponding bits between this APInt and RHS that are...
int32_t exactLogBase2() const
LLVM_ABI APInt reverseBits() const
LLVM_ABI APInt uadd_ov(const APInt &RHS, bool &Overflow) const
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countLeadingZeros() const
bool ule(const APInt &RHS) const
Unsigned less or equal comparison.
APInt shl(unsigned shiftAmt) const
Left-shift function.
LLVM_ABI APInt byteSwap() const
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
LLVM_ABI APInt ssub_ov(const APInt &RHS, bool &Overflow) const
static APInt getBitsSetFrom(unsigned numBits, unsigned loBit)
Constructs an APInt value that has a contiguous range of bits set.
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.
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)
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.
Value * simplifyRangeCheck(CmpPredicate PredL, Value *LHS0, Value *LHS1, CmpPredicate PredR, Value *RHS0, Value *RHS1, Instruction *CtxI, bool Inverted)
Try to fold a signed range checked with lower bound 0 to an unsigned icmp.
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).
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, const Instruction *CtxI=nullptr, unsigned Depth=0)
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, const Instruction *CtxI=nullptr, unsigned Depth=0) const
bool MaskedValueIsZero(const Value *V, const APInt &Mask, const Instruction *CtxI=nullptr, 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...
void computeKnownBits(const Value *V, KnownBits &Known, const Instruction *CtxI, unsigned Depth=0) const
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
const SimplifyQuery & getSimplifyQuery() const
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.
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 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)
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
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.
is_zero< true > m_Zero()
Match any null constant or a vector with all elements equal to 0.
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.
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 bool isKnownNegative(const WithCache< const Value * > &V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the given value is known be negative (i.e.
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 isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, AssumptionCache *AC=nullptr, const Instruction *CtxI=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 matchSimpleRecurrence(const PHINode *P, BinaryOperator *&BO, Value *&Start, Value *&Step)
Attempt to match a simple first order recurrence cycle of the form: iv = phi Ty [Start,...
LLVM_ABI Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Function *CtxF=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
auto dyn_cast_or_null(const Y &Val)
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 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