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);
767 default:
return nullptr;
772 if (!
Known.isNonNegative())
791 if (
LHS->getPredicate() != Pred ||
RHS->getPredicate() != Pred)
816 return Builder.CreateICmp(Pred,
And,
Op);
855 auto tryToMatchSignedTruncationCheck = [](
ICmpInst *ICmp,
Value *&
X,
856 APInt &SignBitMask) ->
bool {
857 const APInt *I01, *I1;
861 I1->ugt(*I01) && I01->
shl(1) == *I1))
873 if (tryToMatchSignedTruncationCheck(ICmp1, X1, HighestBit))
875 else if (tryToMatchSignedTruncationCheck(ICmp0, X1, HighestBit))
880 assert(HighestBit.
isPowerOf2() &&
"expected to be power of two (non-zero)");
884 APInt &UnsetBitsMask) ->
bool {
893 UnsetBitsMask = Res->Mask;
903 if (!tryToDecompose(OtherICmp, X0, UnsetBitsMask))
906 assert(!UnsetBitsMask.
isZero() &&
"empty mask makes no sense.");
921 APInt SignBitsMask = ~(HighestBit - 1U);
928 if (!UnsetBitsMask.
isSubsetOf(SignBitsMask)) {
929 APInt OtherHighestBit = (~UnsetBitsMask) + 1U;
937 return Builder.CreateICmpULT(
X, ConstantInt::get(
X->getType(), HighestBit),
938 CxtI.
getName() +
".simplified");
957 CtPop->dropPoisonGeneratingAnnotations();
959 return Builder.CreateICmpUGT(CtPop, ConstantInt::get(CtPop->getType(), 1));
963 CtPop->dropPoisonGeneratingAnnotations();
965 return Builder.CreateICmpULT(CtPop, ConstantInt::get(CtPop->getType(), 2));
991 CtPop->dropPoisonGeneratingAnnotations();
993 return Builder.CreateICmpEQ(CtPop, ConstantInt::get(CtPop->getType(), 1));
1002 CtPop->dropPoisonGeneratingAnnotations();
1004 return Builder.CreateICmpNE(CtPop, ConstantInt::get(CtPop->getType(), 1));
1018 "Expected equality predicates for masked type of icmps.");
1038 const APInt *BCst, *DCst, *ECst;
1052 if (!BFVTy || !BConst || !DConst || !EConst)
1055 for (
unsigned I = 0;
I != BFVTy->getNumElements(); ++
I) {
1056 const auto *BElt = BConst->getAggregateElement(
I);
1057 const auto *DElt = DConst->getAggregateElement(
I);
1058 const auto *EElt = EConst->getAggregateElement(
I);
1060 if (!BElt || !DElt || !EElt)
1062 if (!isReducible(BElt, DElt, EElt))
1067 if (!isReducible(
B,
D,
E))
1085 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *
E =
nullptr;
1090 std::optional<std::pair<unsigned, unsigned>> MaskPair =
1096 unsigned CmpMask0 = MaskPair->first;
1097 unsigned CmpMask1 = MaskPair->second;
1098 if ((CmpMask0 &
Mask_AllZeros) && (CmpMask1 == compareBMask)) {
1102 }
else if ((CmpMask0 == compareBMask) && (CmpMask1 &
Mask_AllZeros)) {
1113 ICmpInst *UnsignedICmp,
bool IsAnd,
1125 if (
match(UnsignedICmp,
1141 IsAnd && GetKnownNonZeroAndOther(
B,
A))
1142 return Builder.CreateICmpULT(Builder.CreateNeg(
B),
A);
1144 !IsAnd && GetKnownNonZeroAndOther(
B,
A))
1145 return Builder.CreateICmpUGE(Builder.CreateNeg(
B),
A);
1161 return std::nullopt;
1163 unsigned NumOriginalBits =
X->getType()->getScalarSizeInBits();
1164 unsigned NumExtractedBits = V->getType()->getScalarSizeInBits();
1170 Shift->
ule(NumOriginalBits - NumExtractedBits))
1172 return {{
X, 0, NumExtractedBits}};
1179 V = Builder.CreateLShr(V,
P.StartBit);
1181 if (TruncTy != V->getType())
1182 V = Builder.CreateTrunc(V, TruncTy);
1189Value *InstCombinerImpl::foldEqOfParts(
Value *Cmp0,
Value *Cmp1,
bool IsAnd) {
1194 auto GetMatchPart = [&](
Value *CmpV,
1195 unsigned OpNo) -> std::optional<IntPart> {
1204 return {{OpNo == 0 ?
X :
Y, 0, 1}};
1208 return std::nullopt;
1210 if (Pred ==
Cmp->getPredicate())
1219 return std::nullopt;
1228 return std::nullopt;
1230 return std::nullopt;
1235 return {{
I->getOperand(OpNo), From,
C->getBitWidth() - From}};
1238 std::optional<IntPart> L0 = GetMatchPart(Cmp0, 0);
1239 std::optional<IntPart> R0 = GetMatchPart(Cmp0, 1);
1240 std::optional<IntPart> L1 = GetMatchPart(Cmp1, 0);
1241 std::optional<IntPart> R1 = GetMatchPart(Cmp1, 1);
1242 if (!L0 || !R0 || !L1 || !R1)
1247 if (L0->From != L1->From || R0->From != R1->From) {
1248 if (L0->From != R1->From || R0->From != L1->From)
1255 if (L0->StartBit + L0->NumBits != L1->StartBit ||
1256 R0->StartBit + R0->NumBits != R1->StartBit) {
1257 if (L1->StartBit + L1->NumBits != L0->StartBit ||
1258 R1->StartBit + R1->NumBits != R0->StartBit)
1265 IntPart
L = {L0->From, L0->StartBit, L0->NumBits + L1->NumBits};
1266 IntPart
R = {R0->From, R0->StartBit, R0->NumBits + R1->NumBits};
1276 bool IsAnd,
bool IsLogical,
1306 if (!SubstituteCmp) {
1311 SubstituteCmp = Builder.CreateICmp(Pred1,
Y,
C);
1316 return IsAnd ? Builder.CreateLogicalAnd(Cmp0, SubstituteCmp,
"", MDFrom)
1317 : Builder.CreateLogicalOr(Cmp0, SubstituteCmp,
"", MDFrom);
1319 return Builder.CreateBinOp(IsAnd ? Instruction::And : Instruction::Or, Cmp0,
1327Value *InstCombinerImpl::foldAndOrOfICmpsUsingRanges(
ICmpInst *ICmp1,
1331 auto MatchExactRangeCheck =
1332 [](ICmpInst *ICmp) -> std::optional<std::pair<Value *, ConstantRange>> {
1335 return std::nullopt;
1337 CmpPredicate Pred = ICmp->getPredicate();
1343 C->countr_zero() >=
Mask->countr_zero()) {
1344 ConstantRange CR(*
C, *
C - *Mask);
1347 return std::make_pair(
X, CR);
1354 return std::make_pair(
X, CR.
subtract(*C1));
1355 return std::make_pair(
LHS, CR);
1358 auto RC1 = MatchExactRangeCheck(ICmp1);
1362 auto RC2 = MatchExactRangeCheck(ICmp2);
1366 auto &[
V1, CR1] = *RC1;
1367 auto &[V2, CR2] = *RC2;
1373 CR1 = CR1.inverse();
1374 CR2 = CR2.inverse();
1377 Type *Ty =
V1->getType();
1387 APInt LowerDiff = CR1.getLower() ^ CR2.getLower();
1388 APInt UpperDiff = (CR1.getUpper() - 1) ^ (CR2.getUpper() - 1);
1389 APInt CR1Size = CR1.getUpper() - CR1.getLower();
1390 if (!LowerDiff.
isPowerOf2() || LowerDiff != UpperDiff ||
1391 CR1Size != CR2.getUpper() - CR2.getLower())
1394 CR = CR1.getLower().ult(CR2.getLower()) ? CR1 : CR2;
1395 NewV =
Builder.CreateAnd(NewV, ConstantInt::get(Ty, ~LowerDiff));
1403 CR->getEquivalentICmp(NewPred, NewC,
Offset);
1406 NewV =
Builder.CreateAdd(NewV, ConstantInt::get(Ty,
Offset));
1407 return Builder.CreateICmp(NewPred, NewV, ConstantInt::get(Ty, NewC));
1426 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1427 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1439 bool IsAnd,
bool IsLogicalSelect) {
1440 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1441 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1444 if (LHS0 == RHS1 && RHS0 == LHS1) {
1464 if (LHS0 == RHS0 && LHS1 == RHS1) {
1467 unsigned NewPred = IsAnd ? FCmpCodeL & FCmpCodeR : FCmpCodeL | FCmpCodeR;
1487 FastMathFlags FMF =
LHS->getFastMathFlags() &
RHS->getFastMathFlags();
1488 if (IsLogicalSelect) {
1489 Y =
Builder.CreateFreeze(
Y,
Y->getName() +
".fr");
1493 return Builder.CreateFCmpFMF(PredL, LHS0,
Y, FMF);
1498 if (!IsLogicalSelect && IsAnd &&
1514 auto [ClassValRHS, ClassMaskRHS] =
1517 auto [ClassValLHS, ClassMaskLHS] =
1519 if (ClassValLHS == ClassValRHS) {
1520 unsigned CombinedMask = IsAnd ? (ClassMaskLHS & ClassMaskRHS)
1521 : (ClassMaskLHS | ClassMaskRHS);
1522 return Builder.CreateIntrinsic(
1523 Intrinsic::is_fpclass, {ClassValLHS->getType()},
1524 {ClassValLHS,
Builder.getInt32(CombinedMask)});
1552 if (IsLessThanOrLessEqual(IsAnd ? PredR : PredL)) {
1556 if (IsLessThanOrLessEqual(IsAnd ? PredL : PredR)) {
1557 FastMathFlags NewFlag =
LHS->getFastMathFlags();
1558 if (!IsLogicalSelect)
1559 NewFlag |=
RHS->getFastMathFlags();
1563 PredL, FAbs, ConstantFP::get(LHS0->
getType(), *LHSC), NewFlag);
1575 if (!FCmp || !FCmp->hasOneUse())
1578 std::tie(ClassVal, ClassMask) =
1579 fcmpToClassTest(FCmp->getPredicate(), *FCmp->getParent()->getParent(),
1580 FCmp->getOperand(0), FCmp->getOperand(1));
1581 return ClassVal !=
nullptr;
1592 Value *ClassVal0 =
nullptr;
1593 Value *ClassVal1 =
nullptr;
1610 ClassVal0 == ClassVal1) {
1611 unsigned NewClassMask;
1613 case Instruction::And:
1614 NewClassMask = ClassMask0 & ClassMask1;
1616 case Instruction::Or:
1617 NewClassMask = ClassMask0 | ClassMask1;
1619 case Instruction::Xor:
1620 NewClassMask = ClassMask0 ^ ClassMask1;
1629 1, ConstantInt::get(
II->getArgOperand(1)->getType(), NewClassMask));
1636 1, ConstantInt::get(
II->getArgOperand(1)->getType(), NewClassMask));
1641 Builder.CreateIntrinsic(Intrinsic::is_fpclass, {ClassVal0->
getType()},
1642 {ClassVal0,
Builder.getInt32(NewClassMask)});
1656Instruction *InstCombinerImpl::canonicalizeConditionalNegationViaMathToSelect(
1658 assert(
I.getOpcode() == BinaryOperator::Xor &&
"Only for xor!");
1663 !
Cond->getType()->isIntOrIntVectorTy(1) ||
1666 return createSelectInstWithUnknownProfile(
1677 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1678 "Expecting and/or op for fcmp transform");
1697 X->getType() !=
Y->getType())
1701 X->getType() !=
Y->getType())
1718 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1719 "Trying to match De Morgan's Laws with something other than and/or");
1723 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1725 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1751bool InstCombinerImpl::shouldOptimizeCast(
CastInst *CI) {
1761 if (isEliminableCastPair(PrecedingCI, CI))
1789 auto *ZExt =
new ZExtInst(NewOp, DestTy);
1790 ZExt->setNonNeg(Flags.NNeg);
1791 ZExt->andIRFlags(Cast);
1800 return new SExtInst(NewOp, DestTy);
1810 assert(
I.isBitwiseLogicOp() &&
"Unexpected opcode for bitwise logic folding");
1812 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1818 auto FoldBitwiseICmpZeroWithICmp = [&](
Value *Op0,
1819 Value *Op1) -> Instruction * {
1834 auto *BitwiseOp =
Builder.CreateBinOp(LogicOpc, ICmpL, ICmpR);
1836 return new ZExtInst(BitwiseOp, Op0->
getType());
1839 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op0, Op1))
1842 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op1, Op0))
1851 Type *DestTy =
I.getType();
1877 unsigned XNumBits =
X->getType()->getScalarSizeInBits();
1878 unsigned YNumBits =
Y->getType()->getScalarSizeInBits();
1879 if (XNumBits != YNumBits) {
1887 if (XNumBits < YNumBits) {
1888 X =
Builder.CreateCast(CastOpcode,
X,
Y->getType());
1889 }
else if (YNumBits < XNumBits) {
1890 Y =
Builder.CreateCast(CastOpcode,
Y,
X->getType());
1895 Value *NarrowLogic =
Builder.CreateBinOp(LogicOpc,
X,
Y,
I.getName());
1898 if (Disjoint && NewDisjoint)
1899 NewDisjoint->setIsDisjoint(Disjoint->isDisjoint());
1911 if (shouldOptimizeCast(Cast0) && shouldOptimizeCast(Cast1)) {
1912 Value *NewOp =
Builder.CreateBinOp(LogicOpc, Cast0Src, Cast1Src,
1918 NewTrunc->setHasNoUnsignedWrap(
1919 LogicOpc == Instruction::And
1920 ? Trunc0->hasNoUnsignedWrap() || Trunc1->hasNoUnsignedWrap()
1921 : Trunc0->hasNoUnsignedWrap() && Trunc1->hasNoUnsignedWrap());
1922 NewTrunc->setHasNoSignedWrap(Trunc0->hasNoSignedWrap() &&
1923 Trunc1->hasNoSignedWrap());
1933 assert(
I.getOpcode() == Instruction::And);
1934 Value *Op0 =
I.getOperand(0);
1935 Value *Op1 =
I.getOperand(1);
1943 return BinaryOperator::CreateXor(
A,
B);
1959 assert(
I.getOpcode() == Instruction::Or);
1960 Value *Op0 =
I.getOperand(0);
1961 Value *Op1 =
I.getOperand(1);
1986 return BinaryOperator::CreateXor(
A,
B);
2006 Value *Op0 =
And.getOperand(0), *Op1 =
And.getOperand(1);
2027 if (
Opc == Instruction::LShr ||
Opc == Instruction::Shl)
2036 return new ZExtInst(
Builder.CreateAnd(NewBO,
X), Ty);
2044 assert(Opcode == Instruction::And || Opcode == Instruction::Or);
2048 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
2050 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2057 const auto matchNotOrAnd =
2058 [Opcode, FlippedOpcode](
Value *
Op,
auto m_A,
auto m_B,
auto m_C,
2059 Value *&
X,
bool CountUses =
false) ->
bool {
2060 if (CountUses && !
Op->hasOneUse())
2066 return !CountUses ||
X->hasOneUse();
2082 return (Opcode == Instruction::Or)
2083 ? BinaryOperator::CreateAnd(
Xor, Builder.CreateNot(
A))
2092 return (Opcode == Instruction::Or)
2093 ? BinaryOperator::CreateAnd(
Xor, Builder.CreateNot(
B))
2102 Opcode, Builder.CreateBinOp(FlippedOpcode,
B,
C),
A));
2109 Opcode, Builder.CreateBinOp(FlippedOpcode,
A,
C),
B));
2115 if (Opcode == Instruction::Or && Op0->
hasOneUse() &&
2153 return (Opcode == Instruction::Or)
2155 : BinaryOperator::CreateOr(
Xor,
X);
2163 FlippedOpcode, Builder.CreateBinOp(Opcode,
C, Builder.CreateNot(
B)),
2171 FlippedOpcode, Builder.CreateBinOp(Opcode,
B, Builder.CreateNot(
C)),
2191 if (!
X->hasOneUse()) {
2192 Value *YZ = Builder.CreateBinOp(Opcode,
Y, Z);
2196 if (!
Y->hasOneUse()) {
2197 Value *XZ = Builder.CreateBinOp(Opcode,
X, Z);
2217 Type *Ty =
I.getType();
2219 Value *Op0 =
I.getOperand(0);
2220 Value *Op1 =
I.getOperand(1);
2228 unsigned Width = Ty->getScalarSizeInBits();
2232 case Instruction::And:
2233 if (
C->countl_one() < LastOneMath)
2236 case Instruction::Xor:
2237 case Instruction::Or:
2238 if (
C->countl_zero() < LastOneMath)
2245 Value *NewBinOp = Builder.CreateBinOp(OpC,
X, ConstantInt::get(Ty, *
C));
2247 ConstantInt::get(Ty, *C2), Op0);
2254 assert((
I.isBitwiseLogicOp() ||
I.getOpcode() == Instruction::Add) &&
2255 "Unexpected opcode");
2258 Constant *ShiftedC1, *ShiftedC2, *AddC;
2259 Type *Ty =
I.getType();
2275 if (!Op0Inst || !Op1Inst)
2281 if (ShiftOp != Op1Inst->getOpcode())
2285 if (
I.getOpcode() == Instruction::Add && ShiftOp != Instruction::Shl)
2289 I.getOpcode(), ShiftedC1,
Builder.CreateBinOp(ShiftOp, ShiftedC2, AddC));
2305 assert(
I.isBitwiseLogicOp() &&
"Should and/or/xor");
2306 if (!
I.getOperand(0)->hasOneUse())
2313 if (
Y && (!
Y->hasOneUse() ||
X->getIntrinsicID() !=
Y->getIntrinsicID()))
2319 if (!
Y && (!(IID == Intrinsic::bswap || IID == Intrinsic::bitreverse) ||
2324 case Intrinsic::fshl:
2325 case Intrinsic::fshr: {
2326 if (
X->getOperand(2) !=
Y->getOperand(2))
2329 Builder.CreateBinOp(
I.getOpcode(),
X->getOperand(0),
Y->getOperand(0));
2331 Builder.CreateBinOp(
I.getOpcode(),
X->getOperand(1),
Y->getOperand(1));
2336 case Intrinsic::bswap:
2337 case Intrinsic::bitreverse: {
2338 Value *NewOp0 = Builder.CreateBinOp(
2339 I.getOpcode(),
X->getOperand(0),
2340 Y ?
Y->getOperand(0)
2341 : ConstantInt::get(
I.getType(), IID == Intrinsic::bswap
2361 unsigned Depth = 0) {
2369 if (!
I || !
I->isBitwiseLogicOp() ||
Depth >= 3)
2372 if (!
I->hasOneUse())
2373 SimplifyOnly =
true;
2376 SimplifyOnly, IC,
Depth + 1);
2378 SimplifyOnly, IC,
Depth + 1);
2379 if (!NewOp0 && !NewOp1)
2383 NewOp0 =
I->getOperand(0);
2385 NewOp1 =
I->getOperand(1);
2408 APInt Mask = ~*NegP;
2424 Type *Ty =
I.getType();
2425 Value *NewAdd = Builder.CreateAdd(
X, ConstantInt::get(Ty, Mask));
2426 return BinaryOperator::CreateAnd(NewAdd, ConstantInt::get(Ty, *NegP));
2434 bool RHSIsLogical) {
2436 Value *Folded =
nullptr;
2439 if (
Value *Res = foldBooleanAndOr(
LHS,
X,
I, IsAnd,
false))
2440 Folded = RHSIsLogical ?
Builder.CreateLogicalOp(Opcode, Res,
Y)
2441 :
Builder.CreateBinOp(Opcode, Res,
Y);
2444 else if (
Value *Res = foldBooleanAndOr(
LHS,
Y,
I, IsAnd,
false))
2445 Folded = RHSIsLogical ?
Builder.CreateLogicalOp(Opcode,
X, Res)
2446 :
Builder.CreateBinOp(Opcode,
X, Res);
2464 Type *Ty =
I.getType();
2467 SQ.getWithInstruction(&
I)))
2498 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2507 Value *IsZero =
Builder.CreateICmpEQ(
X, ConstantInt::get(Ty, 0));
2517 return createSelectInstWithUnknownProfile(Cmp,
2527 return BinaryOperator::CreateAnd(
Builder.CreateNot(
X),
Y);
2533 Constant *NewC = ConstantInt::get(Ty, *
C & *XorC);
2536 return BinaryOperator::CreateXor(
And, NewC);
2547 APInt Together = *
C & *OrC;
2550 return BinaryOperator::CreateOr(
And, ConstantInt::get(Ty, Together));
2553 unsigned Width = Ty->getScalarSizeInBits();
2554 const APInt *ShiftC;
2556 ShiftC->
ult(Width)) {
2561 Constant *ShAmtC = ConstantInt::get(Ty, ShiftC->
zext(Width));
2562 return BinaryOperator::CreateLShr(Sext, ShAmtC);
2570 return BinaryOperator::CreateLShr(
X, ConstantInt::get(Ty, *ShiftC));
2578 if (Op0->
hasOneUse() &&
C->isPowerOf2() && (*AddC & (*
C - 1)) == 0) {
2579 assert((*
C & *AddC) != 0 &&
"Expected common bit");
2581 return BinaryOperator::CreateXor(NewAnd, Op1);
2588 switch (
B->getOpcode()) {
2589 case Instruction::Xor:
2590 case Instruction::Or:
2591 case Instruction::Mul:
2592 case Instruction::Add:
2593 case Instruction::Sub:
2609 C->isIntN(
X->getType()->getScalarSizeInBits())) {
2610 unsigned XWidth =
X->getType()->getScalarSizeInBits();
2611 Constant *TruncC1 = ConstantInt::get(
X->getType(), C1->
trunc(XWidth));
2613 ?
Builder.CreateBinOp(BOpcode,
X, TruncC1)
2614 :
Builder.CreateBinOp(BOpcode, TruncC1,
X);
2615 Constant *TruncC = ConstantInt::get(
X->getType(),
C->trunc(XWidth));
2625 C->isMask(
X->getType()->getScalarSizeInBits())) {
2627 Value *TrY =
Builder.CreateTrunc(
Y,
X->getType(),
Y->getName() +
".tr");
2635 C->isMask(
X->getType()->getScalarSizeInBits())) {
2637 Value *TrY =
Builder.CreateTrunc(
Y,
X->getType(),
Y->getName() +
".tr");
2654 Value *NewRHS =
Builder.CreateAnd(
Y, Op1,
Y->getName() +
".masked");
2660 Value *NewLHS =
Builder.CreateAnd(
X, Op1,
X->getName() +
".masked");
2669 if (
C->isPowerOf2() &&
2672 int Log2C =
C->exactLogBase2();
2675 int BitNum = IsShiftLeft ? Log2C - Log2ShiftC : Log2ShiftC - Log2C;
2676 assert(BitNum >= 0 &&
"Expected demanded bits to handle impossible mask");
2677 Value *Cmp =
Builder.CreateICmpEQ(
X, ConstantInt::get(Ty, BitNum));
2678 return createSelectInstWithUnknownProfile(Cmp, ConstantInt::get(Ty, *
C),
2698 return createSelectInstWithUnknownProfile(
2709 if (Cmp && Cmp->isNullValue()) {
2715 return createSelectInstWithUnknownProfile(
2733 !
Builder.GetInsertBlock()->getParent()->hasFnAttribute(
2734 Attribute::NoImplicitFloat)) {
2749 APInt(Ty->getScalarSizeInBits(),
2750 Ty->getScalarSizeInBits() -
2751 X->getType()->getScalarSizeInBits())))) {
2752 auto *SExt =
Builder.CreateSExt(
X, Ty,
X->getName() +
".signext");
2753 return BinaryOperator::CreateAnd(SExt, Op1);
2759 if (
I.getType()->isIntOrIntVectorTy(1)) {
2762 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
true))
2767 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
true))
2782 return BinaryOperator::CreateAnd(Op0,
B);
2785 return BinaryOperator::CreateAnd(Op1,
B);
2793 if (NotC !=
nullptr)
2794 return BinaryOperator::CreateAnd(Op0, NotC);
2803 if (NotC !=
nullptr)
2804 return BinaryOperator::CreateAnd(Op1, NotC);
2813 return BinaryOperator::CreateAnd(
A,
B);
2821 return BinaryOperator::CreateAnd(
A,
B);
2829 return BinaryOperator::CreateAnd(
Builder.CreateNot(
A),
B);
2837 return BinaryOperator::CreateAnd(
Builder.CreateNot(
A),
B);
2841 foldBooleanAndOr(Op0, Op1,
I,
true,
false))
2846 if (
auto *V = reassociateBooleanAndOr(Op0,
X,
Y,
I,
true,
2852 if (
auto *V = reassociateBooleanAndOr(Op1,
X,
Y,
I,
true,
2860 if (
Instruction *CastedAnd = foldCastedBitwiseLogic(
I))
2873 A->getType()->isIntOrIntVectorTy(1))
2879 A->getType()->isIntOrIntVectorTy(1))
2884 A->getType()->isIntOrIntVectorTy(1))
2885 return createSelectInstWithUnknownProfile(
2886 A,
Builder.CreateAnd(
B, ConstantInt::get(Ty, 1)),
2892 if (
A->getType()->isIntOrIntVectorTy(1))
2896 return createSelectInstWithUnknownProfile(
2906 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2908 return createSelectInstWithUnknownProfile(IsNeg,
Y,
2916 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2918 return createSelectInstWithUnknownProfile(IsNeg,
2928 Value *Start =
nullptr, *Step =
nullptr;
2936 return Canonicalized;
2938 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
2950 return BinaryOperator::CreateAnd(V, Op1);
2954 return BinaryOperator::CreateAnd(Op0, V);
2964 bool MatchBitReversals) {
2972 for (
auto *Inst : Insts) {
2973 Inst->setDebugLoc(
I.getDebugLoc());
2979std::optional<std::pair<Intrinsic::ID, SmallVector<Value *, 3>>>
2983 assert(
Or.getOpcode() == BinaryOperator::Or &&
"Expecting or instruction");
2985 unsigned Width =
Or.getType()->getScalarSizeInBits();
2990 return std::nullopt;
2998 Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
3004 return std::nullopt;
3007 if (Or0->
getOpcode() == BinaryOperator::LShr) {
3013 Or1->
getOpcode() == BinaryOperator::LShr &&
3014 "Illegal or(shift,shift) pair");
3018 auto matchShiftAmount = [&](
Value *L,
Value *R,
unsigned Width) ->
Value * {
3020 const APInt *LI, *RI;
3022 if (LI->
ult(Width) && RI->
ult(Width) && (*LI + *RI) == Width)
3023 return ConstantInt::get(L->getType(), *LI);
3047 if (ShVal0 != ShVal1)
3058 unsigned Mask = Width - 1;
3066 Value *XPlusOne =
nullptr;
3093 Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, Width);
3095 ShAmt = matchShiftAmount(ShAmt1, ShAmt0, Width);
3099 return std::nullopt;
3101 FShiftArgs = {ShVal0, ShVal1, ShAmt};
3118 const APInt *ZextHighShlAmt;
3121 return std::nullopt;
3125 return std::nullopt;
3127 unsigned HighSize =
High->getType()->getScalarSizeInBits();
3128 unsigned LowSize =
Low->getType()->getScalarSizeInBits();
3131 if (ZextHighShlAmt->
ult(LowSize) || ZextHighShlAmt->
ugt(Width - HighSize))
3132 return std::nullopt;
3142 const APInt *ZextLowShlAmt;
3149 if (*ZextLowShlAmt + *ZextHighShlAmt != Width)
3155 ZextLowShlAmt->
ule(Width - LowSize) &&
"Invalid concat");
3164 FShiftArgs = {U, U, ConstantInt::get(Or0->
getType(), *ZextHighShlAmt)};
3169 if (FShiftArgs.
empty())
3170 return std::nullopt;
3172 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
3173 return std::make_pair(IID, FShiftArgs);
3179 auto [IID, FShiftArgs] = *Opt;
3190 assert(
Or.getOpcode() == Instruction::Or &&
"bswap requires an 'or'");
3191 Value *Op0 =
Or.getOperand(0), *Op1 =
Or.getOperand(1);
3194 unsigned Width = Ty->getScalarSizeInBits();
3195 if ((Width & 1) != 0)
3197 unsigned HalfWidth = Width / 2;
3204 Value *LowerSrc, *ShlVal, *UpperSrc;
3215 Value *NewLower = Builder.CreateZExt(
Lo, Ty);
3216 Value *NewUpper = Builder.CreateZExt(
Hi, Ty);
3217 NewUpper = Builder.CreateShl(NewUpper, HalfWidth);
3218 Value *BinOp = Builder.CreateDisjointOr(NewLower, NewUpper);
3219 return Builder.CreateIntrinsic(
id, Ty, BinOp);
3224 Value *LowerBSwap, *UpperBSwap;
3227 return ConcatIntrinsicCalls(Intrinsic::bswap, UpperBSwap, LowerBSwap);
3231 Value *LowerBRev, *UpperBRev;
3234 return ConcatIntrinsicCalls(Intrinsic::bitreverse, UpperBRev, LowerBRev);
3246 return Builder.CreateSExt(
X, Ty);
3254 for (
unsigned i = 0; i != NumElts; ++i) {
3257 if (!EltC1 || !EltC2)
3276 Type *Ty =
A->getType();
3292 if (
A->getType()->isIntOrIntVectorTy()) {
3294 if (NumSignBits ==
A->getType()->getScalarSizeInBits() &&
3317 Cond->getType()->isIntOrIntVectorTy(1)) {
3343 Cond->getType()->isIntOrIntVectorTy(1) &&
3357 Value *
D,
bool InvertFalseVal) {
3363 if (
Value *
Cond = getSelectCondition(
A,
C, InvertFalseVal)) {
3368 Type *SelTy =
A->getType();
3371 unsigned Elts = VecTy->getElementCount().getKnownMinValue();
3375 Type *EltTy =
Builder.getIntNTy(SelEltSize / Elts);
3392 bool IsAnd,
bool IsLogical,
3399 IsAnd ?
LHS->getInversePredicate() :
LHS->getPredicate();
3401 IsAnd ?
RHS->getInversePredicate() :
RHS->getPredicate();
3407 !(
LHS->hasOneUse() ||
RHS->hasOneUse()))
3410 auto MatchRHSOp = [LHS0, CInt](
const Value *RHSOp) {
3413 (CInt->
isZero() && RHSOp == LHS0);
3427 return Builder.CreateICmp(
3429 Builder.CreateSub(LHS0, ConstantInt::get(LHS0->
getType(), *CInt + 1)),
3439 const SimplifyQuery Q =
SQ.getWithInstruction(&
I);
3442 Value *LHS0 =
LHS->getOperand(0), *RHS0 =
RHS->getOperand(0);
3443 Value *LHS1 =
LHS->getOperand(1), *RHS1 =
RHS->getOperand(1);
3445 const APInt *LHSC =
nullptr, *RHSC =
nullptr;
3452 if (LHS0 == RHS1 && LHS1 == RHS0) {
3456 if (LHS0 == RHS0 && LHS1 == RHS1) {
3459 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
3482 RHS->setSameSign(
false);
3508 if (IsAnd && !IsLogical)
3534 return Builder.CreateICmp(PredL, NewOr,
3545 return Builder.CreateICmp(PredL, NewAnd,
3565 const APInt *AndC, *SmallC =
nullptr, *BigC =
nullptr;
3579 if (SmallC && BigC) {
3580 unsigned BigBitSize = BigC->getBitWidth();
3587 APInt
N = SmallC->
zext(BigBitSize) | *BigC;
3589 return Builder.CreateICmp(PredL, NewAnd, NewVal);
3599 bool TrueIfSignedL, TrueIfSignedR;
3605 if ((TrueIfSignedL && !TrueIfSignedR &&
3608 (!TrueIfSignedL && TrueIfSignedR &&
3612 return Builder.CreateIsNeg(NewXor);
3615 if ((TrueIfSignedL && !TrueIfSignedR &&
3618 (!TrueIfSignedL && TrueIfSignedR &&
3622 return Builder.CreateIsNotNeg(NewXor);
3631 if (LHS0 == RHS0 && PredL == PredR &&
3633 !
I.getFunction()->hasFnAttribute(Attribute::NoImplicitFloat) &&
3636 X->getType()->getScalarType()->isIEEELikeFPTy() &&
3637 APFloat(
X->getType()->getScalarType()->getFltSemantics(), *MaskC)
3639 ((LHSC->
isZero() && *RHSC == *MaskC) ||
3640 (RHSC->
isZero() && *LHSC == *MaskC)))
3644 return foldAndOrOfICmpsUsingRanges(
LHS,
RHS, IsAnd);
3659 SQ.getWithInstruction(&
I)))
3664 if (
Value *Res = foldAndOrOfICmps(LHSCmp, RHSCmp,
I, IsAnd, IsLogical))
3669 if (
Value *Res = foldLogicOfFCmps(LHSCmp, RHSCmp, IsAnd, IsLogical))
3680 assert(
I.getOpcode() == Instruction::Or &&
3681 "Simplification only supports or at the moment.");
3683 Value *Cmp1, *Cmp2, *Cmp3, *Cmp4;
3690 return Builder.CreateXor(Cmp1, Cmp4);
3692 return Builder.CreateXor(Cmp1, Cmp3);
3722 const unsigned EltBitWidth = EltTy->getBitWidth();
3724 if (TargetBitWidth % EltBitWidth != 0 || ShlAmt % EltBitWidth != 0)
3726 const unsigned TargetEltWidth = TargetBitWidth / EltBitWidth;
3727 const unsigned ShlEltAmt = ShlAmt / EltBitWidth;
3729 const unsigned MaskIdx =
3730 DL.isLittleEndian() ? ShlEltAmt : TargetEltWidth - ShlEltAmt - 1;
3732 VecOffset =
static_cast<int64_t
>(VecIdx) -
static_cast<int64_t
>(MaskIdx);
3733 Mask.resize(TargetEltWidth);
3747 Mask.resize(SrcTy->getNumElements());
3761 const unsigned NumVecElts = VecTy->getNumElements();
3762 bool FoundVecOffset =
false;
3763 for (
unsigned Idx = 0; Idx < ShuffleMask.size(); ++Idx) {
3766 const unsigned ShuffleIdx = ShuffleMask[Idx];
3767 if (ShuffleIdx >= NumVecElts) {
3768 const unsigned ConstIdx = ShuffleIdx - NumVecElts;
3771 if (!ConstElt || !ConstElt->isNullValue())
3776 if (FoundVecOffset) {
3777 if (VecOffset + Idx != ShuffleIdx)
3780 if (ShuffleIdx < Idx)
3782 VecOffset = ShuffleIdx - Idx;
3783 FoundVecOffset =
true;
3787 return FoundVecOffset;
3800 bool AlreadyInsertedMaskedElt = Mask.test(InsertIdx);
3802 if (!AlreadyInsertedMaskedElt)
3803 Mask.reset(InsertIdx);
3812 assert(
I.getOpcode() == Instruction::Or);
3813 Value *LhsVec, *RhsVec;
3814 int64_t LhsVecOffset, RhsVecOffset;
3822 if (LhsVec != RhsVec || LhsVecOffset != RhsVecOffset)
3826 const unsigned ZeroVecIdx =
3829 for (
unsigned Idx : Mask.set_bits()) {
3830 assert(LhsVecOffset + Idx >= 0);
3831 ShuffleMask[Idx] = LhsVecOffset + Idx;
3834 Value *MaskedVec = Builder.CreateShuffleVector(
3836 I.getName() +
".v");
3862 const APInt *ShiftedMaskConst =
nullptr;
3869 if (!
match(MaskedOp0,
3874 if (LShrAmt > ShlAmt)
3876 Offset = ShlAmt - LShrAmt;
3878 Mask = ShiftedMaskConst ? ShiftedMaskConst->
shl(LShrAmt)
3880 Int->getType()->getScalarSizeInBits(), LShrAmt);
3890 Value *LhsInt, *RhsInt;
3891 APInt LhsMask, RhsMask;
3893 bool IsLhsShlNUW, IsLhsShlNSW, IsRhsShlNUW, IsRhsShlNSW;
3900 if (LhsInt != RhsInt || LhsOffset != RhsOffset)
3903 APInt Mask = LhsMask | RhsMask;
3906 Value *Res = Builder.CreateShl(
3908 Builder.CreateAnd(LhsInt, Mask, LhsInt->
getName() +
".mask"), DestTy,
3910 ConstantInt::get(DestTy, LhsOffset),
"", IsLhsShlNUW && IsRhsShlNUW,
3911 IsLhsShlNSW && IsRhsShlNSW);
3936 return std::nullopt;
3939 Value *Original =
nullptr;
3940 const APInt *Mask =
nullptr;
3941 const APInt *MulConst =
nullptr;
3944 if (MulConst->
isZero() || Mask->isZero())
3945 return std::nullopt;
3947 return std::optional<DecomposedBitMaskMul>(
3948 {Original, *MulConst, *Mask,
3954 const APInt *EqZero =
nullptr, *NeZero =
nullptr;
3958 auto ICmpDecompose =
3961 if (!ICmpDecompose.has_value())
3962 return std::nullopt;
3966 if (ICmpDecompose->X->getType() != V->getType())
3967 return std::nullopt;
3970 ICmpDecompose->C.isZero());
3975 if (!EqZero->
isZero() || NeZero->isZero())
3976 return std::nullopt;
3978 if (!ICmpDecompose->Mask.isPowerOf2() || ICmpDecompose->Mask.isZero())
3979 return std::nullopt;
3981 if (!NeZero->urem(ICmpDecompose->Mask).isZero())
3982 return std::nullopt;
3984 return std::optional<DecomposedBitMaskMul>(
3985 {ICmpDecompose->X, NeZero->udiv(ICmpDecompose->Mask),
3986 ICmpDecompose->Mask,
false,
false});
3989 return std::nullopt;
4005 if (Decomp0->isCombineableWith(*Decomp1)) {
4006 Value *NewAnd = Builder.CreateAnd(
4008 ConstantInt::get(Decomp0->X->getType(), Decomp0->Mask + Decomp1->Mask));
4010 return Builder.CreateMul(
4011 NewAnd, ConstantInt::get(NewAnd->
getType(), Decomp1->Factor),
"",
4012 Decomp0->NUW && Decomp1->NUW, Decomp0->NSW && Decomp1->NSW);
4031 if (
Value *Res = foldDisjointOr(
LHS,
X))
4032 return Builder.CreateDisjointOr(Res,
Y);
4033 if (
Value *Res = foldDisjointOr(
LHS,
Y))
4034 return Builder.CreateDisjointOr(Res,
X);
4038 if (
Value *Res = foldDisjointOr(
X,
RHS))
4039 return Builder.CreateDisjointOr(Res,
Y);
4040 if (
Value *Res = foldDisjointOr(
Y,
RHS))
4041 return Builder.CreateDisjointOr(Res,
X);
4055 const APInt *C1, *C2;
4064 Constant *NewC = ConstantInt::get(
X->getType(), C2->
udiv(*C1));
4085 return Builder.CreateBinaryIntrinsic(Intrinsic::abs,
X,
4086 Builder.getFalse());
4104 bool MayNeedFreeze = SelOp0 && SelOp1 &&
4105 match(SelOp1->getTrueValue(),
4110 Value *C2 =
nullptr, *A2 =
nullptr, *B2 =
nullptr;
4119 return createSelectInstWithUnknownProfile(
C,
A,
B);
4135 bool MayNeedFreeze = SelOp0 && SelOp1 &&
4136 match(SelOp0->getTrueValue(),
4141 Value *C2 =
nullptr, *A2 =
nullptr, *B2 =
nullptr;
4150 return createSelectInstWithUnknownProfile(
C,
B,
A);
4164 SQ.getWithInstruction(&
I)))
4200 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
4201 Type *Ty =
I.getType();
4202 if (Ty->isIntOrIntVectorTy(1)) {
4205 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
false))
4210 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
false))
4247 if (
Value *Res = foldDisjointOr(
I.getOperand(0),
I.getOperand(1)))
4250 if (
Value *Res = reassociateDisjointOr(
I.getOperand(0),
I.getOperand(1)))
4261 return BinaryOperator::CreateXor(
Or, ConstantInt::get(Ty, *CV));
4268 Value *IncrementY =
Builder.CreateAdd(
Y, ConstantInt::get(Ty, 1));
4269 return BinaryOperator::CreateMul(
X, IncrementY);
4286 if (
I.getType()->isIntOrIntVectorTy(1) &&
4299 const APInt *C0, *C1;
4305 return BinaryOperator::CreateOr(
Builder.CreateAnd(
X, *C0),
B);
4308 return BinaryOperator::CreateOr(
Builder.CreateAnd(
X, *C1),
A);
4312 return BinaryOperator::CreateXor(
Builder.CreateAnd(
X, *C0),
B);
4315 return BinaryOperator::CreateXor(
Builder.CreateAnd(
X, *C1),
A);
4318 if ((*C0 & *C1).
isZero()) {
4323 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
4324 return BinaryOperator::CreateAnd(
A, C01);
4330 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
4331 return BinaryOperator::CreateAnd(
B, C01);
4335 const APInt *C2, *C3;
4340 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
4341 return BinaryOperator::CreateAnd(
Or, C01);
4351 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D))
4353 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B))
4355 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D))
4357 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B))
4359 if (
Value *V = matchSelectFromAndOr(
B,
D,
A,
C))
4361 if (
Value *V = matchSelectFromAndOr(
B,
D,
C,
A))
4363 if (
Value *V = matchSelectFromAndOr(
D,
B,
A,
C))
4365 if (
Value *V = matchSelectFromAndOr(
D,
B,
C,
A))
4374 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D,
true))
4376 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B,
true))
4378 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D,
true))
4380 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B,
true))
4389 return BinaryOperator::CreateOr(Op0,
C);
4396 return BinaryOperator::CreateOr(Op1,
C);
4402 bool SwappedForXor =
false;
4405 SwappedForXor =
true;
4412 return BinaryOperator::CreateOr(Op0,
B);
4414 return BinaryOperator::CreateOr(Op0,
A);
4419 return BinaryOperator::CreateOr(
A,
B);
4447 return BinaryOperator::CreateOr(Nand,
C);
4455 foldBooleanAndOr(Op0, Op1,
I,
false,
false))
4460 if (
auto *V = reassociateBooleanAndOr(Op0,
X,
Y,
I,
false,
4466 if (
auto *V = reassociateBooleanAndOr(Op1,
X,
Y,
I,
false,
4486 A->getType()->isIntOrIntVectorTy(1))
4487 return createSelectInstWithUnknownProfile(
4506 Value *Inner =
Builder.CreateOr(
A, Op1,
"", IsDisjointOuter);
4508 return IsDisjointOuter && IsDisjointInner
4509 ? BinaryOperator::CreateDisjointOr(Inner, CI)
4510 : BinaryOperator::CreateOr(Inner, CI);
4517 Value *
X =
nullptr, *
Y =
nullptr;
4536 return createSelectInstWithUnknownProfile(NewICmpInst,
AllOnes,
X);
4549 return BinaryOperator::CreateXor(
A,
B);
4565 Value *
Mul, *Ov, *MulIsNotZero, *UMulWithOv;
4583 return BinaryOperator::CreateAnd(NotNullA, NotNullB);
4592 const APInt *C1, *C2;
4607 : C2->
uadd_ov(*C1, Overflow));
4611 return BinaryOperator::CreateOr(Ov, NewCmp);
4630 ConstantInt::get(Ty, Ty->getScalarSizeInBits() - 1),
X);
4636 Value *Start =
nullptr, *Step =
nullptr;
4654 return BinaryOperator::CreateOr(
4666 return BinaryOperator::CreateOr(
4674 return Canonicalized;
4676 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
4696 !
Builder.GetInsertBlock()->getParent()->hasFnAttribute(
4697 Attribute::NoImplicitFloat)) {
4711 if ((KnownX.
One & *C2) == *C2)
4712 return BinaryOperator::CreateAnd(
X, ConstantInt::get(Ty, *C1 | *C2));
4721 return BinaryOperator::CreateOr(V, Op1);
4725 return BinaryOperator::CreateOr(Op0, V);
4740 unsigned BitWidth = Ty->getScalarSizeInBits();
4747 I,
Builder.CreateIntrinsic(Ty, Intrinsic::scmp,
4748 {X, Constant::getNullValue(Ty)}));
4758 assert(
I.getOpcode() == Instruction::Xor);
4759 Value *Op0 =
I.getOperand(0);
4760 Value *Op1 =
I.getOperand(1);
4771 return BinaryOperator::CreateXor(
A,
B);
4779 return BinaryOperator::CreateXor(
A,
B);
4787 return BinaryOperator::CreateXor(
A,
B);
4809 assert(
I.getOpcode() == Instruction::Xor &&
I.getOperand(0) ==
LHS &&
4810 I.getOperand(1) ==
RHS &&
"Should be 'xor' with these operands");
4813 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
4814 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
4817 if (LHS0 == RHS1 && LHS1 == RHS0) {
4821 if (LHS0 == RHS0 && LHS1 == RHS1) {
4824 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
4829 const APInt *LC, *RC;
4838 bool TrueIfSignedL, TrueIfSignedR;
4843 return TrueIfSignedL == TrueIfSignedR ?
Builder.CreateIsNeg(XorLR) :
4844 Builder.CreateIsNotNeg(XorLR);
4854 if (CRUnion && CRIntersect)
4855 if (
auto CR = CRUnion->exactIntersectWith(CRIntersect->inverse())) {
4856 if (CR->isFullSet())
4858 if (CR->isEmptySet())
4863 CR->getEquivalentICmp(NewPred, NewC,
Offset);
4870 NewV =
Builder.CreateAdd(NewV, ConstantInt::get(Ty,
Offset));
4871 return Builder.CreateICmp(NewPred, NewV,
4872 ConstantInt::get(Ty, NewC));
4904 ICmpInst *
X =
nullptr, *
Y =
nullptr;
4905 if (OrICmp ==
LHS && AndICmp ==
RHS) {
4910 if (OrICmp ==
RHS && AndICmp ==
LHS) {
4917 Y->setPredicate(
Y->getInversePredicate());
4919 if (!
Y->hasOneUse()) {
4926 Builder.SetInsertPoint(
Y->getParent(), ++(
Y->getIterator()));
4930 Y->replaceUsesWithIf(NotY,
4931 [NotY](Use &U) {
return U.getUser() != NotY; });
4969 Value *NewA = Builder.CreateAnd(
D, NotM);
4970 return BinaryOperator::CreateXor(NewA,
X);
4976 Type *EltTy =
C->getType()->getScalarType();
4980 Value *NotC = Builder.CreateNot(
C);
4981 Value *
RHS = Builder.CreateAnd(
B, NotC);
4982 return BinaryOperator::CreateOr(
LHS,
RHS);
4997 return A ==
C ||
A ==
D ||
B ==
C ||
B ==
D;
5005 Value *NotY = Builder.CreateNot(
Y);
5006 return BinaryOperator::CreateOr(
X, NotY);
5013 Value *NotX = Builder.CreateNot(
X);
5014 return BinaryOperator::CreateOr(
Y, NotX);
5024 assert(
Xor.getOpcode() == Instruction::Xor &&
"Expected an xor instruction.");
5030 Value *Op0 =
Xor.getOperand(0), *Op1 =
Xor.getOperand(1);
5038 Op1->
hasNUses(2) && *ShAmt == Ty->getScalarSizeInBits() - 1 &&
5043 Value *IsNeg = Builder.CreateIsNeg(
A);
5046 Value *NegA =
Add->hasNoUnsignedWrap()
5048 : Builder.CreateNeg(
A,
"",
Add->hasNoSignedWrap());
5057 return I &&
I->getInsertionPointAfterDef() &&
5065 auto InsertPt =
I->getInsertionPointAfterDef();
5067 "freelyInvert requires an instruction with a valid insertion point");
5070 Op->replaceUsesWithIf(NotOp,
5071 [NotOp](
Use &U) {
return U.getUser() != NotOp; });
5112 auto InsertPt =
I.getInsertionPointAfterDef();
5113 assert(InsertPt &&
"sinkNotIntoLogicalOp requires an instruction with a "
5114 "valid insertion point");
5115 Builder.SetInsertPoint(*InsertPt);
5118 NewLogicOp =
Builder.CreateBinOp(NewOpc, Op0, Op1,
I.getName() +
".not");
5121 Builder.CreateLogicalOp(NewOpc, Op0, Op1,
I.getName() +
".not",
5124 SI->swapProfMetadata();
5148 Value *NotOp0 =
nullptr;
5149 Value *NotOp1 =
nullptr;
5150 Value **OpToInvert =
nullptr;
5167 Builder.SetInsertPoint(*
I.getInsertionPointAfterDef());
5170 NewBinOp =
Builder.CreateBinOp(NewOpc, Op0, Op1,
I.getName() +
".not");
5172 NewBinOp =
Builder.CreateLogicalOp(NewOpc, Op0, Op1,
I.getName() +
".not");
5195 Type *Ty =
I.getType();
5198 Value *NotY = Builder.CreateNot(
Y,
Y->getName() +
".not");
5199 return BinaryOperator::CreateOr(
X, NotY);
5202 Value *NotY = Builder.CreateNot(
Y,
Y->getName() +
".not");
5206 SI->swapProfMetadata();
5214 return BinaryOperator::CreateAnd(
X, NotY);
5221 SI->swapProfMetadata();
5226 BinaryOperator *NotVal;
5233 return BinaryOperator::CreateAnd(DecX, NotY);
5238 return BinaryOperator::CreateAShr(
X,
Y);
5244 return BinaryOperator::CreateAShr(
X,
Y);
5251 return new SExtInst(IsNotNeg, Ty);
5278 return BinaryOperator::CreateAdd(
Builder.CreateNot(
X),
Y);
5301 return new BitCastInst(
X, Ty);
5307 X->getType()->isIntOrIntVectorTy(1)) {
5311 return new BitCastInst(Sext, Ty);
5322 if (
II &&
II->hasOneUse()) {
5326 Value *InvMaxMin =
Builder.CreateBinaryIntrinsic(InvID,
X, NotY);
5330 if (
II->getIntrinsicID() == Intrinsic::is_fpclass) {
5333 1, ConstantInt::get(ClassMask->
getType(),
5349 Value *TV = Sel->getTrueValue();
5350 Value *FV = Sel->getFalseValue();
5353 bool InvertibleT = (CmpT && CmpT->hasOneUse()) ||
isa<Constant>(TV);
5354 bool InvertibleF = (CmpF && CmpF->hasOneUse()) ||
isa<Constant>(FV);
5355 if (InvertibleT && InvertibleF) {
5357 CmpT->setPredicate(CmpT->getInversePredicate());
5361 CmpF->setPredicate(CmpF->getInversePredicate());
5392 Value *NotC = Builder.CreateNot(AddC);
5395 return BinaryOperator::CreateAnd(NewSub, Mask);
5406 SQ.getWithInstruction(&
I)))
5436 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5444 return BinaryOperator::CreateXor(XorAC,
Y);
5447 return BinaryOperator::CreateXor(XorBC,
X);
5457 return BinaryOperator::CreateDisjointOr(Op0, Op1);
5459 return BinaryOperator::CreateOr(Op0, Op1);
5476 return BinaryOperator::CreateXor(
5499 *CA ==
X->getType()->getScalarSizeInBits() - 1 &&
5503 return createSelectInstWithUnknownProfile(IsNotNeg, Op1,
5508 Type *Ty =
I.getType();
5516 return BinaryOperator::CreateSub(ConstantInt::get(Ty, *
C + *RHSC),
X);
5520 return BinaryOperator::CreateAdd(
X, ConstantInt::get(Ty, *
C + *RHSC));
5525 return BinaryOperator::CreateXor(
X, ConstantInt::get(Ty, *
C ^ *RHSC));
5531 if (
II &&
II->hasOneUse() && *RHSC == Ty->getScalarSizeInBits() - 1) {
5533 if ((IID == Intrinsic::ctlz || IID == Intrinsic::cttz) &&
5536 IID = (IID == Intrinsic::ctlz) ? Intrinsic::cttz : Intrinsic::ctlz;
5549 return BinaryOperator::CreateShl(NotX, ConstantInt::get(Ty, *
C));
5555 return BinaryOperator::CreateLShr(NotX, ConstantInt::get(Ty, *
C));
5573 !
Builder.GetInsertBlock()->getParent()->hasFnAttribute(
5574 Attribute::NoImplicitFloat)) {
5597 auto *Opnd0 =
Builder.CreateLShr(
X, C2);
5598 Opnd0->takeName(Op0);
5599 return BinaryOperator::CreateXor(Opnd0, ConstantInt::get(Ty, FoldConst));
5612 return BinaryOperator::CreateAnd(
X,
Builder.CreateNot(Op0));
5616 return BinaryOperator::CreateAnd(
X,
Builder.CreateNot(Op1));
5621 return BinaryOperator::CreateAnd(Op0,
Builder.CreateNot(
X));
5629 return BinaryOperator::CreateAnd(Op1,
Builder.CreateNot(
X));
5635 return BinaryOperator::CreateXor(
5641 return BinaryOperator::CreateXor(
5647 return BinaryOperator::CreateOr(
A,
B);
5651 return BinaryOperator::CreateOr(
A,
B);
5661 return BinaryOperator::CreateOr(
A,
B);
5676 if (
B ==
C ||
B ==
D)
5682 return BinaryOperator::CreateAnd(
Builder.CreateXor(
B,
C), NotA);
5687 if (
I.getType()->isIntOrIntVectorTy(1) &&
5692 if (
B ==
C ||
B ==
D) {
5703 ? createSelectInstWithUnknownProfile(
A, NotB,
C)
5710 if (
Value *V = foldXorOfICmps(LHS, RHS,
I))
5713 if (
Instruction *CastedXor = foldCastedBitwiseLogic(
I))
5726 return BinaryOperator::CreateXor(
Builder.CreateXor(
X,
Y), C1);
5732 return Canonicalized;
5734 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
5737 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 * foldAndOrOfICmpsWithConstEq(ICmpInst *Cmp0, ICmpInst *Cmp1, 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 Value * foldIsPowerOf2OrZero(ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd, InstCombiner::BuilderTy &Builder, InstCombinerImpl &IC)
Fold (icmp eq ctpop(X) 1) | (icmp eq X 0) into (icmp ult ctpop(X) 2) and fold (icmp ne ctpop(X) 1) & ...
static Value * foldBitmaskMul(Value *Op0, Value *Op1, InstCombiner::BuilderTy &Builder)
(A & N) * C + (A & M) * C -> (A & (N + M)) & C This also accepts the equivalent select form of (A & N...
static unsigned conjugateICmpMask(unsigned Mask)
Convert an analysis of a masked ICmp into its equivalent if all boolean operations had the opposite s...
static Instruction * foldNotXor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static Value * foldLogOpOfMaskedICmps(Value *LHS, Value *RHS, bool IsAnd, bool IsLogical, InstCombiner::BuilderTy &Builder, const SimplifyQuery &Q)
Try to fold (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E) into a single (icmp(A & X) ==/!...
static Value * getFCmpValue(unsigned Code, Value *LHS, Value *RHS, InstCombiner::BuilderTy &Builder, FMFSource FMF)
This is the complement of getFCmpCode, which turns an opcode and two operands into either a FCmp inst...
static bool matchIsFPClassLikeFCmp(Value *Op, Value *&ClassVal, uint64_t &ClassMask)
Match an fcmp against a special value that performs a test possible by llvm.is.fpclass.
static Value * foldSignedTruncationCheck(ICmpInst *ICmp0, ICmpInst *ICmp1, Instruction &CxtI, InstCombiner::BuilderTy &Builder)
General pattern: X & Y.
static Instruction * visitMaskedMerge(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
If we have a masked merge, in the canonical form of: (assuming that A only has one use....
static Instruction * canonicalizeAbs(BinaryOperator &Xor, InstCombiner::BuilderTy &Builder)
Canonicalize a shifty way to code absolute value to the more common pattern that uses negation and se...
static Value * foldIsPowerOf2(ICmpInst *Cmp0, ICmpInst *Cmp1, bool JoinedByAnd, InstCombiner::BuilderTy &Builder, InstCombinerImpl &IC)
Reduce a pair of compares that check if a value has exactly 1 bit set.
static Value * foldUnsignedUnderflowCheck(ICmpInst *ZeroICmp, ICmpInst *UnsignedICmp, bool IsAnd, const SimplifyQuery &Q, InstCombiner::BuilderTy &Builder)
Commuted variants are assumed to be handled by calling this function again with the parameters swappe...
static Instruction * foldOrToXor(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
static Value * simplifyAndOrWithOpReplaced(Value *V, Value *Op, Value *RepOp, bool SimplifyOnly, InstCombinerImpl &IC, unsigned Depth=0)
static Instruction * matchDeMorgansLaws(BinaryOperator &I, InstCombiner &IC)
Match variations of De Morgan's Laws: (~A & ~B) == (~(A | B)) (~A | ~B) == (~(A & B))
static Value * foldLogOpOfMaskedICmpsAsymmetric(Value *LHS, Value *RHS, bool IsAnd, Value *A, Value *B, Value *C, Value *D, Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR, unsigned LHSMask, unsigned RHSMask, InstCombiner::BuilderTy &Builder)
Try to fold (icmp(A & B) ==/!= 0) &/| (icmp(A & D) ==/!= E) into a single (icmp(A & X) ==/!...
static 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 Instruction * foldLogicCastConstant(BinaryOperator &Logic, CastInst *Cast, InstCombinerImpl &IC)
Fold {and,or,xor} (cast X), C.
static Value * foldAndOrOfICmpEqConstantAndICmp(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, bool IsLogical, IRBuilderBase &Builder)
static bool canFreelyInvert(InstCombiner &IC, Value *Op, Instruction *IgnoredUser)
static Value * foldNegativePower2AndShiftedMask(Value *A, Value *B, Value *D, Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR, InstCombiner::BuilderTy &Builder)
Try to fold (icmp(A & B) == 0) & (icmp(A & D) != E) into (icmp A u< D) iff B is a contiguous set of o...
static Value * matchIsFiniteTest(InstCombiner::BuilderTy &Builder, FCmpInst *LHS, FCmpInst *RHS)
and (fcmp ord x, 0), (fcmp u* x, inf) -> fcmp o* x, inf
static Value * foldPowerOf2AndShiftedMask(ICmpInst *Cmp0, ICmpInst *Cmp1, bool JoinedByAnd, InstCombiner::BuilderTy &Builder)
Try to fold ((icmp X u< P) & (icmp(X & M) != M)) or ((icmp X s> -1) & (icmp(X & M) !...
static Value * 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 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 Value * foldAndOrOfICmpsWithPow2AndWithZero(InstCombiner::BuilderTy &Builder, ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, const SimplifyQuery &Q)
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 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.
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,...
Predicate getPredicate() const
Return the predicate for this instruction.
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 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)
Instruction * visitAnd(BinaryOperator &I)
bool sinkNotIntoOtherHandOfLogicalOp(Instruction &I)
Instruction * foldBinopWithPhiOperands(BinaryOperator &BO)
For a binary operator with 2 phi operands, try to hoist the binary operation before the phi.
Instruction * foldAddLikeCommutative(Value *LHS, Value *RHS, bool NSW, bool NUW)
Common transforms for add / disjoint or.
Value * simplifyRangeCheck(ICmpInst *Cmp0, ICmpInst *Cmp1, bool Inverted)
Try to fold a signed range checked with lower bound 0 to an unsigned icmp.
Instruction * tryFoldInstWithCtpopWithNot(Instruction *I)
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.
CmpClass_match< LHS, RHS, ICmpInst, true > m_c_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)
Matches ExtractElementInst.
cst_pred_ty< is_nonnegative > m_NonNegative()
Match an integer or vector of non-negative values.
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.
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