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;
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");
958 CtPop->dropPoisonGeneratingAnnotations();
960 return Builder.CreateICmpUGT(CtPop, ConstantInt::get(CtPop->getType(), 1));
964 CtPop->dropPoisonGeneratingAnnotations();
966 return Builder.CreateICmpULT(CtPop, ConstantInt::get(CtPop->getType(), 2));
993 CtPop->dropPoisonGeneratingAnnotations();
995 return Builder.CreateICmpEQ(CtPop, ConstantInt::get(CtPop->getType(), 1));
1005 CtPop->dropPoisonGeneratingAnnotations();
1007 return Builder.CreateICmpNE(CtPop, ConstantInt::get(CtPop->getType(), 1));
1021 "Expected equality predicates for masked type of icmps.");
1041 const APInt *BCst, *DCst, *ECst;
1055 if (!BFVTy || !BConst || !DConst || !EConst)
1058 for (
unsigned I = 0;
I != BFVTy->getNumElements(); ++
I) {
1059 const auto *BElt = BConst->getAggregateElement(
I);
1060 const auto *DElt = DConst->getAggregateElement(
I);
1061 const auto *EElt = EConst->getAggregateElement(
I);
1063 if (!BElt || !DElt || !EElt)
1065 if (!isReducible(BElt, DElt, EElt))
1070 if (!isReducible(
B,
D,
E))
1088 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *
E =
nullptr;
1093 std::optional<std::pair<unsigned, unsigned>> MaskPair =
1099 unsigned CmpMask0 = MaskPair->first;
1100 unsigned CmpMask1 = MaskPair->second;
1101 if ((CmpMask0 &
Mask_AllZeros) && (CmpMask1 == compareBMask)) {
1105 }
else if ((CmpMask0 == compareBMask) && (CmpMask1 &
Mask_AllZeros)) {
1116 ICmpInst *UnsignedICmp,
bool IsAnd,
1128 if (
match(UnsignedICmp,
1144 IsAnd && GetKnownNonZeroAndOther(
B,
A))
1145 return Builder.CreateICmpULT(Builder.CreateNeg(
B),
A);
1147 !IsAnd && GetKnownNonZeroAndOther(
B,
A))
1148 return Builder.CreateICmpUGE(Builder.CreateNeg(
B),
A);
1164 return std::nullopt;
1166 unsigned NumOriginalBits =
X->getType()->getScalarSizeInBits();
1167 unsigned NumExtractedBits = V->getType()->getScalarSizeInBits();
1173 Shift->
ule(NumOriginalBits - NumExtractedBits))
1175 return {{
X, 0, NumExtractedBits}};
1182 V = Builder.CreateLShr(V,
P.StartBit);
1184 if (TruncTy != V->getType())
1185 V = Builder.CreateTrunc(V, TruncTy);
1192Value *InstCombinerImpl::foldEqOfParts(
Value *Cmp0,
Value *Cmp1,
bool IsAnd) {
1197 auto GetMatchPart = [&](
Value *CmpV,
1198 unsigned OpNo) -> std::optional<IntPart> {
1207 return {{OpNo == 0 ?
X :
Y, 0, 1}};
1211 return std::nullopt;
1213 if (Pred ==
Cmp->getPredicate())
1222 return std::nullopt;
1231 return std::nullopt;
1233 return std::nullopt;
1238 return {{
I->getOperand(OpNo), From,
C->getBitWidth() - From}};
1241 std::optional<IntPart> L0 = GetMatchPart(Cmp0, 0);
1242 std::optional<IntPart> R0 = GetMatchPart(Cmp0, 1);
1243 std::optional<IntPart> L1 = GetMatchPart(Cmp1, 0);
1244 std::optional<IntPart> R1 = GetMatchPart(Cmp1, 1);
1245 if (!L0 || !R0 || !L1 || !R1)
1250 if (L0->From != L1->From || R0->From != R1->From) {
1251 if (L0->From != R1->From || R0->From != L1->From)
1258 if (L0->StartBit + L0->NumBits != L1->StartBit ||
1259 R0->StartBit + R0->NumBits != R1->StartBit) {
1260 if (L1->StartBit + L1->NumBits != L0->StartBit ||
1261 R1->StartBit + R1->NumBits != R0->StartBit)
1268 IntPart
L = {L0->From, L0->StartBit, L0->NumBits + L1->NumBits};
1269 IntPart
R = {R0->From, R0->StartBit, R0->NumBits + R1->NumBits};
1279 bool IsAnd,
bool IsLogical,
1309 if (!SubstituteCmp) {
1314 SubstituteCmp = Builder.CreateICmp(Pred1,
Y,
C);
1319 return IsAnd ? Builder.CreateLogicalAnd(Cmp0, SubstituteCmp,
"", MDFrom)
1320 : Builder.CreateLogicalOr(Cmp0, SubstituteCmp,
"", MDFrom);
1322 return Builder.CreateBinOp(IsAnd ? Instruction::And : Instruction::Or, Cmp0,
1330Value *InstCombinerImpl::foldAndOrOfICmpsUsingRanges(
ICmpInst *ICmp1,
1334 auto MatchExactRangeCheck =
1335 [](ICmpInst *ICmp) -> std::optional<std::pair<Value *, ConstantRange>> {
1338 return std::nullopt;
1340 CmpPredicate Pred = ICmp->getPredicate();
1346 C->countr_zero() >=
Mask->countr_zero()) {
1347 ConstantRange CR(*
C, *
C - *Mask);
1350 return std::make_pair(
X, CR);
1357 return std::make_pair(
X, CR.
subtract(*C1));
1358 return std::make_pair(
LHS, CR);
1361 auto RC1 = MatchExactRangeCheck(ICmp1);
1365 auto RC2 = MatchExactRangeCheck(ICmp2);
1369 auto &[V1, CR1] = *RC1;
1370 auto &[V2, CR2] = *RC2;
1376 CR1 = CR1.inverse();
1377 CR2 = CR2.inverse();
1380 Type *Ty = V1->getType();
1390 APInt LowerDiff = CR1.getLower() ^ CR2.getLower();
1391 APInt UpperDiff = (CR1.getUpper() - 1) ^ (CR2.getUpper() - 1);
1392 APInt CR1Size = CR1.getUpper() - CR1.getLower();
1393 if (!LowerDiff.
isPowerOf2() || LowerDiff != UpperDiff ||
1394 CR1Size != CR2.getUpper() - CR2.getLower())
1397 CR = CR1.getLower().ult(CR2.getLower()) ? CR1 : CR2;
1398 NewV =
Builder.CreateAnd(NewV, ConstantInt::get(Ty, ~LowerDiff));
1406 CR->getEquivalentICmp(NewPred, NewC,
Offset);
1409 NewV =
Builder.CreateAdd(NewV, ConstantInt::get(Ty,
Offset));
1410 return Builder.CreateICmp(NewPred, NewV, ConstantInt::get(Ty, NewC));
1429 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1430 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1442 bool IsAnd,
bool IsLogicalSelect) {
1443 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1444 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1447 if (LHS0 == RHS1 && RHS0 == LHS1) {
1467 if (LHS0 == RHS0 && LHS1 == RHS1) {
1470 unsigned NewPred = IsAnd ? FCmpCodeL & FCmpCodeR : FCmpCodeL | FCmpCodeR;
1479 if (!IsLogicalSelect &&
1492 return Builder.CreateFCmpFMF(PredL, LHS0, RHS0,
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();
1562 Builder.CreateUnaryIntrinsic(Intrinsic::fabs, LHS0, NewFlag);
1564 PredL, FAbs, ConstantFP::get(LHS0->
getType(), *LHSC), NewFlag);
1576 if (!FCmp || !FCmp->hasOneUse())
1579 std::tie(ClassVal, ClassMask) =
1580 fcmpToClassTest(FCmp->getPredicate(), *FCmp->getParent()->getParent(),
1581 FCmp->getOperand(0), FCmp->getOperand(1));
1582 return ClassVal !=
nullptr;
1593 Value *ClassVal0 =
nullptr;
1594 Value *ClassVal1 =
nullptr;
1595 uint64_t ClassMask0, ClassMask1;
1611 ClassVal0 == ClassVal1) {
1612 unsigned NewClassMask;
1614 case Instruction::And:
1615 NewClassMask = ClassMask0 & ClassMask1;
1617 case Instruction::Or:
1618 NewClassMask = ClassMask0 | ClassMask1;
1620 case Instruction::Xor:
1621 NewClassMask = ClassMask0 ^ ClassMask1;
1630 1, ConstantInt::get(
II->getArgOperand(1)->getType(), NewClassMask));
1637 1, ConstantInt::get(
II->getArgOperand(1)->getType(), NewClassMask));
1641 CallInst *NewClass =
1642 Builder.CreateIntrinsic(Intrinsic::is_fpclass, {ClassVal0->
getType()},
1643 {ClassVal0,
Builder.getInt32(NewClassMask)});
1657Instruction *InstCombinerImpl::canonicalizeConditionalNegationViaMathToSelect(
1659 assert(
I.getOpcode() == BinaryOperator::Xor &&
"Only for xor!");
1664 !
Cond->getType()->isIntOrIntVectorTy(1) ||
1667 return createSelectInstWithUnknownProfile(
1678 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1679 "Expecting and/or op for fcmp transform");
1698 X->getType() !=
Y->getType())
1702 X->getType() !=
Y->getType())
1719 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1720 "Trying to match De Morgan's Laws with something other than and/or");
1724 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1726 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1752bool InstCombinerImpl::shouldOptimizeCast(
CastInst *CI) {
1762 if (isEliminableCastPair(PrecedingCI, CI))
1790 auto *ZExt =
new ZExtInst(NewOp, DestTy);
1791 ZExt->setNonNeg(Flags.NNeg);
1792 ZExt->andIRFlags(Cast);
1801 return new SExtInst(NewOp, DestTy);
1811 assert(
I.isBitwiseLogicOp() &&
"Unexpected opcode for bitwise logic folding");
1813 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1819 auto FoldBitwiseICmpZeroWithICmp = [&](
Value *Op0,
1820 Value *Op1) -> Instruction * {
1835 auto *BitwiseOp =
Builder.CreateBinOp(LogicOpc, ICmpL, ICmpR);
1837 return new ZExtInst(BitwiseOp, Op0->
getType());
1840 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op0, Op1))
1843 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op1, Op0))
1852 Type *DestTy =
I.getType();
1878 unsigned XNumBits =
X->getType()->getScalarSizeInBits();
1879 unsigned YNumBits =
Y->getType()->getScalarSizeInBits();
1880 if (XNumBits != YNumBits) {
1888 if (XNumBits < YNumBits) {
1889 X =
Builder.CreateCast(CastOpcode,
X,
Y->getType());
1890 }
else if (YNumBits < XNumBits) {
1891 Y =
Builder.CreateCast(CastOpcode,
Y,
X->getType());
1896 Value *NarrowLogic =
Builder.CreateBinOp(LogicOpc,
X,
Y,
I.getName());
1899 if (Disjoint && NewDisjoint)
1900 NewDisjoint->setIsDisjoint(Disjoint->isDisjoint());
1912 if (shouldOptimizeCast(Cast0) && shouldOptimizeCast(Cast1)) {
1913 Value *NewOp =
Builder.CreateBinOp(LogicOpc, Cast0Src, Cast1Src,
1923 assert(
I.getOpcode() == Instruction::And);
1924 Value *Op0 =
I.getOperand(0);
1925 Value *Op1 =
I.getOperand(1);
1933 return BinaryOperator::CreateXor(
A,
B);
1949 assert(
I.getOpcode() == Instruction::Or);
1950 Value *Op0 =
I.getOperand(0);
1951 Value *Op1 =
I.getOperand(1);
1976 return BinaryOperator::CreateXor(
A,
B);
1996 Value *Op0 =
And.getOperand(0), *Op1 =
And.getOperand(1);
2017 if (
Opc == Instruction::LShr ||
Opc == Instruction::Shl)
2026 return new ZExtInst(
Builder.CreateAnd(NewBO,
X), Ty);
2034 assert(Opcode == Instruction::And || Opcode == Instruction::Or);
2038 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
2040 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2047 const auto matchNotOrAnd =
2048 [Opcode, FlippedOpcode](
Value *
Op,
auto m_A,
auto m_B,
auto m_C,
2049 Value *&
X,
bool CountUses =
false) ->
bool {
2050 if (CountUses && !
Op->hasOneUse())
2056 return !CountUses ||
X->hasOneUse();
2072 return (Opcode == Instruction::Or)
2073 ? BinaryOperator::CreateAnd(
Xor, Builder.CreateNot(
A))
2082 return (Opcode == Instruction::Or)
2083 ? BinaryOperator::CreateAnd(
Xor, Builder.CreateNot(
B))
2092 Opcode, Builder.CreateBinOp(FlippedOpcode,
B,
C),
A));
2099 Opcode, Builder.CreateBinOp(FlippedOpcode,
A,
C),
B));
2105 if (Opcode == Instruction::Or && Op0->
hasOneUse() &&
2143 return (Opcode == Instruction::Or)
2145 : BinaryOperator::CreateOr(
Xor,
X);
2153 FlippedOpcode, Builder.CreateBinOp(Opcode,
C, Builder.CreateNot(
B)),
2161 FlippedOpcode, Builder.CreateBinOp(Opcode,
B, Builder.CreateNot(
C)),
2181 if (!
X->hasOneUse()) {
2182 Value *YZ = Builder.CreateBinOp(Opcode,
Y, Z);
2186 if (!
Y->hasOneUse()) {
2187 Value *XZ = Builder.CreateBinOp(Opcode,
X, Z);
2207 Type *Ty =
I.getType();
2209 Value *Op0 =
I.getOperand(0);
2210 Value *Op1 =
I.getOperand(1);
2218 unsigned Width = Ty->getScalarSizeInBits();
2222 case Instruction::And:
2223 if (
C->countl_one() < LastOneMath)
2226 case Instruction::Xor:
2227 case Instruction::Or:
2228 if (
C->countl_zero() < LastOneMath)
2235 Value *NewBinOp = Builder.CreateBinOp(OpC,
X, ConstantInt::get(Ty, *
C));
2237 ConstantInt::get(Ty, *C2), Op0);
2244 assert((
I.isBitwiseLogicOp() ||
I.getOpcode() == Instruction::Add) &&
2245 "Unexpected opcode");
2248 Constant *ShiftedC1, *ShiftedC2, *AddC;
2249 Type *Ty =
I.getType();
2265 if (!Op0Inst || !Op1Inst)
2271 if (ShiftOp != Op1Inst->getOpcode())
2275 if (
I.getOpcode() == Instruction::Add && ShiftOp != Instruction::Shl)
2279 I.getOpcode(), ShiftedC1,
Builder.CreateBinOp(ShiftOp, ShiftedC2, AddC));
2295 assert(
I.isBitwiseLogicOp() &&
"Should and/or/xor");
2296 if (!
I.getOperand(0)->hasOneUse())
2303 if (
Y && (!
Y->hasOneUse() ||
X->getIntrinsicID() !=
Y->getIntrinsicID()))
2309 if (!
Y && (!(IID == Intrinsic::bswap || IID == Intrinsic::bitreverse) ||
2314 case Intrinsic::fshl:
2315 case Intrinsic::fshr: {
2316 if (
X->getOperand(2) !=
Y->getOperand(2))
2319 Builder.CreateBinOp(
I.getOpcode(),
X->getOperand(0),
Y->getOperand(0));
2321 Builder.CreateBinOp(
I.getOpcode(),
X->getOperand(1),
Y->getOperand(1));
2326 case Intrinsic::bswap:
2327 case Intrinsic::bitreverse: {
2328 Value *NewOp0 = Builder.CreateBinOp(
2329 I.getOpcode(),
X->getOperand(0),
2330 Y ?
Y->getOperand(0)
2331 : ConstantInt::get(
I.getType(), IID == Intrinsic::bswap
2351 unsigned Depth = 0) {
2359 if (!
I || !
I->isBitwiseLogicOp() ||
Depth >= 3)
2362 if (!
I->hasOneUse())
2363 SimplifyOnly =
true;
2366 SimplifyOnly, IC,
Depth + 1);
2368 SimplifyOnly, IC,
Depth + 1);
2369 if (!NewOp0 && !NewOp1)
2373 NewOp0 =
I->getOperand(0);
2375 NewOp1 =
I->getOperand(1);
2391 bool RHSIsLogical) {
2393 Value *Folded =
nullptr;
2396 if (
Value *Res = foldBooleanAndOr(
LHS,
X,
I, IsAnd,
false))
2397 Folded = RHSIsLogical ?
Builder.CreateLogicalOp(Opcode, Res,
Y)
2398 :
Builder.CreateBinOp(Opcode, Res,
Y);
2401 else if (
Value *Res = foldBooleanAndOr(
LHS,
Y,
I, IsAnd,
false))
2402 Folded = RHSIsLogical ?
Builder.CreateLogicalOp(Opcode,
X, Res)
2403 :
Builder.CreateBinOp(Opcode,
X, Res);
2421 Type *Ty =
I.getType();
2424 SQ.getWithInstruction(&
I)))
2455 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2464 Value *IsZero =
Builder.CreateICmpEQ(
X, ConstantInt::get(Ty, 0));
2474 return createSelectInstWithUnknownProfile(Cmp,
2484 return BinaryOperator::CreateAnd(
Builder.CreateNot(
X),
Y);
2490 Constant *NewC = ConstantInt::get(Ty, *
C & *XorC);
2493 return BinaryOperator::CreateXor(
And, NewC);
2504 APInt Together = *
C & *OrC;
2507 return BinaryOperator::CreateOr(
And, ConstantInt::get(Ty, Together));
2510 unsigned Width = Ty->getScalarSizeInBits();
2511 const APInt *ShiftC;
2513 ShiftC->
ult(Width)) {
2518 Constant *ShAmtC = ConstantInt::get(Ty, ShiftC->
zext(Width));
2519 return BinaryOperator::CreateLShr(Sext, ShAmtC);
2527 return BinaryOperator::CreateLShr(
X, ConstantInt::get(Ty, *ShiftC));
2535 if (Op0->
hasOneUse() &&
C->isPowerOf2() && (*AddC & (*
C - 1)) == 0) {
2536 assert((*
C & *AddC) != 0 &&
"Expected common bit");
2538 return BinaryOperator::CreateXor(NewAnd, Op1);
2545 switch (
B->getOpcode()) {
2546 case Instruction::Xor:
2547 case Instruction::Or:
2548 case Instruction::Mul:
2549 case Instruction::Add:
2550 case Instruction::Sub:
2566 C->isIntN(
X->getType()->getScalarSizeInBits())) {
2567 unsigned XWidth =
X->getType()->getScalarSizeInBits();
2568 Constant *TruncC1 = ConstantInt::get(
X->getType(), C1->
trunc(XWidth));
2570 ?
Builder.CreateBinOp(BOpcode,
X, TruncC1)
2571 :
Builder.CreateBinOp(BOpcode, TruncC1,
X);
2572 Constant *TruncC = ConstantInt::get(
X->getType(),
C->trunc(XWidth));
2582 C->isMask(
X->getType()->getScalarSizeInBits())) {
2584 Value *TrY =
Builder.CreateTrunc(
Y,
X->getType(),
Y->getName() +
".tr");
2592 C->isMask(
X->getType()->getScalarSizeInBits())) {
2594 Value *TrY =
Builder.CreateTrunc(
Y,
X->getType(),
Y->getName() +
".tr");
2611 Value *NewRHS =
Builder.CreateAnd(
Y, Op1,
Y->getName() +
".masked");
2617 Value *NewLHS =
Builder.CreateAnd(
X, Op1,
X->getName() +
".masked");
2626 if (
C->isPowerOf2() &&
2629 int Log2C =
C->exactLogBase2();
2632 int BitNum = IsShiftLeft ? Log2C - Log2ShiftC : Log2ShiftC - Log2C;
2633 assert(BitNum >= 0 &&
"Expected demanded bits to handle impossible mask");
2634 Value *Cmp =
Builder.CreateICmpEQ(
X, ConstantInt::get(Ty, BitNum));
2635 return createSelectInstWithUnknownProfile(Cmp, ConstantInt::get(Ty, *
C),
2655 return createSelectInstWithUnknownProfile(
2666 if (Cmp && Cmp->isNullValue()) {
2672 return createSelectInstWithUnknownProfile(
2690 !
Builder.GetInsertBlock()->getParent()->hasFnAttribute(
2691 Attribute::NoImplicitFloat)) {
2695 Value *FAbs =
Builder.CreateUnaryIntrinsic(Intrinsic::fabs, CastOp);
2706 APInt(Ty->getScalarSizeInBits(),
2707 Ty->getScalarSizeInBits() -
2708 X->getType()->getScalarSizeInBits())))) {
2709 auto *SExt =
Builder.CreateSExt(
X, Ty,
X->getName() +
".signext");
2710 return BinaryOperator::CreateAnd(SExt, Op1);
2716 if (
I.getType()->isIntOrIntVectorTy(1)) {
2719 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
true))
2724 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
true))
2739 return BinaryOperator::CreateAnd(Op0,
B);
2742 return BinaryOperator::CreateAnd(Op1,
B);
2750 if (NotC !=
nullptr)
2751 return BinaryOperator::CreateAnd(Op0, NotC);
2760 if (NotC !=
nullptr)
2761 return BinaryOperator::CreateAnd(Op1,
Builder.CreateNot(
C));
2770 return BinaryOperator::CreateAnd(
A,
B);
2778 return BinaryOperator::CreateAnd(
A,
B);
2786 return BinaryOperator::CreateAnd(
Builder.CreateNot(
A),
B);
2794 return BinaryOperator::CreateAnd(
Builder.CreateNot(
A),
B);
2798 foldBooleanAndOr(Op0, Op1,
I,
true,
false))
2803 if (
auto *V = reassociateBooleanAndOr(Op0,
X,
Y,
I,
true,
2809 if (
auto *V = reassociateBooleanAndOr(Op1,
X,
Y,
I,
true,
2817 if (
Instruction *CastedAnd = foldCastedBitwiseLogic(
I))
2830 A->getType()->isIntOrIntVectorTy(1))
2836 A->getType()->isIntOrIntVectorTy(1))
2841 A->getType()->isIntOrIntVectorTy(1))
2842 return createSelectInstWithUnknownProfile(
2843 A,
Builder.CreateAnd(
B, ConstantInt::get(Ty, 1)),
2849 if (
A->getType()->isIntOrIntVectorTy(1))
2853 return createSelectInstWithUnknownProfile(
2863 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2865 return createSelectInstWithUnknownProfile(IsNeg,
Y,
2873 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2875 return createSelectInstWithUnknownProfile(IsNeg,
2885 Value *Start =
nullptr, *Step =
nullptr;
2893 return Canonicalized;
2895 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
2907 return BinaryOperator::CreateAnd(V, Op1);
2911 return BinaryOperator::CreateAnd(Op0, V);
2918 bool MatchBitReversals) {
2926 for (
auto *Inst : Insts) {
2927 Inst->setDebugLoc(
I.getDebugLoc());
2933std::optional<std::pair<Intrinsic::ID, SmallVector<Value *, 3>>>
2937 assert(
Or.getOpcode() == BinaryOperator::Or &&
"Expecting or instruction");
2939 unsigned Width =
Or.getType()->getScalarSizeInBits();
2944 return std::nullopt;
2952 Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
2958 return std::nullopt;
2961 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2967 Or1->
getOpcode() == BinaryOperator::LShr &&
2968 "Illegal or(shift,shift) pair");
2972 auto matchShiftAmount = [&](
Value *L,
Value *R,
unsigned Width) ->
Value * {
2974 const APInt *LI, *RI;
2976 if (LI->
ult(Width) && RI->
ult(Width) && (*LI + *RI) == Width)
2977 return ConstantInt::get(L->getType(), *LI);
3001 if (ShVal0 != ShVal1)
3012 unsigned Mask = Width - 1;
3036 Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, Width);
3038 ShAmt = matchShiftAmount(ShAmt1, ShAmt0, Width);
3042 return std::nullopt;
3044 FShiftArgs = {ShVal0, ShVal1, ShAmt};
3061 const APInt *ZextHighShlAmt;
3064 return std::nullopt;
3068 return std::nullopt;
3070 unsigned HighSize =
High->getType()->getScalarSizeInBits();
3071 unsigned LowSize =
Low->getType()->getScalarSizeInBits();
3074 if (ZextHighShlAmt->
ult(LowSize) || ZextHighShlAmt->
ugt(Width - HighSize))
3075 return std::nullopt;
3085 const APInt *ZextLowShlAmt;
3092 if (*ZextLowShlAmt + *ZextHighShlAmt != Width)
3098 ZextLowShlAmt->
ule(Width - LowSize) &&
"Invalid concat");
3107 FShiftArgs = {U, U, ConstantInt::get(Or0->
getType(), *ZextHighShlAmt)};
3112 if (FShiftArgs.
empty())
3113 return std::nullopt;
3115 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
3116 return std::make_pair(IID, FShiftArgs);
3122 auto [IID, FShiftArgs] = *Opt;
3133 assert(
Or.getOpcode() == Instruction::Or &&
"bswap requires an 'or'");
3134 Value *Op0 =
Or.getOperand(0), *Op1 =
Or.getOperand(1);
3137 unsigned Width = Ty->getScalarSizeInBits();
3138 if ((Width & 1) != 0)
3140 unsigned HalfWidth = Width / 2;
3147 Value *LowerSrc, *ShlVal, *UpperSrc;
3158 Value *NewLower = Builder.CreateZExt(
Lo, Ty);
3159 Value *NewUpper = Builder.CreateZExt(
Hi, Ty);
3160 NewUpper = Builder.CreateShl(NewUpper, HalfWidth);
3161 Value *BinOp = Builder.CreateOr(NewLower, NewUpper);
3162 return Builder.CreateIntrinsic(
id, Ty, BinOp);
3167 Value *LowerBSwap, *UpperBSwap;
3170 return ConcatIntrinsicCalls(Intrinsic::bswap, UpperBSwap, LowerBSwap);
3174 Value *LowerBRev, *UpperBRev;
3177 return ConcatIntrinsicCalls(Intrinsic::bitreverse, UpperBRev, LowerBRev);
3189 return Builder.CreateSExt(
X, Ty);
3197 for (
unsigned i = 0; i != NumElts; ++i) {
3200 if (!EltC1 || !EltC2)
3219 Type *Ty =
A->getType();
3235 if (
A->getType()->isIntOrIntVectorTy()) {
3237 if (NumSignBits ==
A->getType()->getScalarSizeInBits() &&
3260 Cond->getType()->isIntOrIntVectorTy(1)) {
3286 Cond->getType()->isIntOrIntVectorTy(1) &&
3300 Value *
D,
bool InvertFalseVal) {
3306 if (
Value *
Cond = getSelectCondition(
A,
C, InvertFalseVal)) {
3311 Type *SelTy =
A->getType();
3314 unsigned Elts = VecTy->getElementCount().getKnownMinValue();
3318 Type *EltTy =
Builder.getIntNTy(SelEltSize / Elts);
3335 bool IsAnd,
bool IsLogical,
3342 IsAnd ?
LHS->getInversePredicate() :
LHS->getPredicate();
3344 IsAnd ?
RHS->getInversePredicate() :
RHS->getPredicate();
3350 !(
LHS->hasOneUse() ||
RHS->hasOneUse()))
3353 auto MatchRHSOp = [LHS0, CInt](
const Value *RHSOp) {
3356 (CInt->
isZero() && RHSOp == LHS0);
3370 return Builder.CreateICmp(
3372 Builder.CreateSub(LHS0, ConstantInt::get(LHS0->
getType(), *CInt + 1)),
3382 const SimplifyQuery Q =
SQ.getWithInstruction(&
I);
3385 Value *LHS0 =
LHS->getOperand(0), *RHS0 =
RHS->getOperand(0);
3386 Value *LHS1 =
LHS->getOperand(1), *RHS1 =
RHS->getOperand(1);
3388 const APInt *LHSC =
nullptr, *RHSC =
nullptr;
3395 if (LHS0 == RHS1 && LHS1 == RHS0) {
3399 if (LHS0 == RHS0 && LHS1 == RHS1) {
3402 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
3425 RHS->setSameSign(
false);
3451 if (IsAnd && !IsLogical)
3477 return Builder.CreateICmp(PredL, NewOr,
3488 return Builder.CreateICmp(PredL, NewAnd,
3508 const APInt *AndC, *SmallC =
nullptr, *BigC =
nullptr;
3522 if (SmallC && BigC) {
3523 unsigned BigBitSize = BigC->getBitWidth();
3530 APInt
N = SmallC->
zext(BigBitSize) | *BigC;
3532 return Builder.CreateICmp(PredL, NewAnd, NewVal);
3542 bool TrueIfSignedL, TrueIfSignedR;
3548 if ((TrueIfSignedL && !TrueIfSignedR &&
3551 (!TrueIfSignedL && TrueIfSignedR &&
3555 return Builder.CreateIsNeg(NewXor);
3558 if ((TrueIfSignedL && !TrueIfSignedR &&
3561 (!TrueIfSignedL && TrueIfSignedR &&
3565 return Builder.CreateIsNotNeg(NewXor);
3574 if (LHS0 == RHS0 && PredL == PredR &&
3576 !
I.getFunction()->hasFnAttribute(Attribute::NoImplicitFloat) &&
3579 X->getType()->getScalarType()->isIEEELikeFPTy() &&
3580 APFloat(
X->getType()->getScalarType()->getFltSemantics(), *MaskC)
3582 ((LHSC->
isZero() && *RHSC == *MaskC) ||
3583 (RHSC->
isZero() && *LHSC == *MaskC)))
3587 return foldAndOrOfICmpsUsingRanges(
LHS,
RHS, IsAnd);
3602 SQ.getWithInstruction(&
I)))
3607 if (
Value *Res = foldAndOrOfICmps(LHSCmp, RHSCmp,
I, IsAnd, IsLogical))
3612 if (
Value *Res = foldLogicOfFCmps(LHSCmp, RHSCmp, IsAnd, IsLogical))
3623 assert(
I.getOpcode() == Instruction::Or &&
3624 "Simplification only supports or at the moment.");
3626 Value *Cmp1, *Cmp2, *Cmp3, *Cmp4;
3633 return Builder.CreateXor(Cmp1, Cmp4);
3635 return Builder.CreateXor(Cmp1, Cmp3);
3665 const unsigned EltBitWidth = EltTy->getBitWidth();
3667 if (TargetBitWidth % EltBitWidth != 0 || ShlAmt % EltBitWidth != 0)
3669 const unsigned TargetEltWidth = TargetBitWidth / EltBitWidth;
3670 const unsigned ShlEltAmt = ShlAmt / EltBitWidth;
3672 const unsigned MaskIdx =
3673 DL.isLittleEndian() ? ShlEltAmt : TargetEltWidth - ShlEltAmt - 1;
3675 VecOffset =
static_cast<int64_t
>(VecIdx) -
static_cast<int64_t
>(MaskIdx);
3676 Mask.resize(TargetEltWidth);
3690 Mask.resize(SrcTy->getNumElements());
3704 const unsigned NumVecElts = VecTy->getNumElements();
3705 bool FoundVecOffset =
false;
3706 for (
unsigned Idx = 0; Idx < ShuffleMask.size(); ++Idx) {
3709 const unsigned ShuffleIdx = ShuffleMask[Idx];
3710 if (ShuffleIdx >= NumVecElts) {
3711 const unsigned ConstIdx = ShuffleIdx - NumVecElts;
3714 if (!ConstElt || !ConstElt->isNullValue())
3719 if (FoundVecOffset) {
3720 if (VecOffset + Idx != ShuffleIdx)
3723 if (ShuffleIdx < Idx)
3725 VecOffset = ShuffleIdx - Idx;
3726 FoundVecOffset =
true;
3730 return FoundVecOffset;
3743 bool AlreadyInsertedMaskedElt = Mask.test(InsertIdx);
3745 if (!AlreadyInsertedMaskedElt)
3746 Mask.reset(InsertIdx);
3755 assert(
I.getOpcode() == Instruction::Or);
3756 Value *LhsVec, *RhsVec;
3757 int64_t LhsVecOffset, RhsVecOffset;
3765 if (LhsVec != RhsVec || LhsVecOffset != RhsVecOffset)
3769 const unsigned ZeroVecIdx =
3772 for (
unsigned Idx : Mask.set_bits()) {
3773 assert(LhsVecOffset + Idx >= 0);
3774 ShuffleMask[Idx] = LhsVecOffset + Idx;
3777 Value *MaskedVec = Builder.CreateShuffleVector(
3779 I.getName() +
".v");
3805 const APInt *ShiftedMaskConst =
nullptr;
3812 if (!
match(MaskedOp0,
3817 if (LShrAmt > ShlAmt)
3819 Offset = ShlAmt - LShrAmt;
3821 Mask = ShiftedMaskConst ? ShiftedMaskConst->
shl(LShrAmt)
3823 Int->getType()->getScalarSizeInBits(), LShrAmt);
3833 Value *LhsInt, *RhsInt;
3834 APInt LhsMask, RhsMask;
3836 bool IsLhsShlNUW, IsLhsShlNSW, IsRhsShlNUW, IsRhsShlNSW;
3843 if (LhsInt != RhsInt || LhsOffset != RhsOffset)
3846 APInt Mask = LhsMask | RhsMask;
3849 Value *Res = Builder.CreateShl(
3851 Builder.CreateAnd(LhsInt, Mask, LhsInt->
getName() +
".mask"), DestTy,
3853 ConstantInt::get(DestTy, LhsOffset),
"", IsLhsShlNUW && IsRhsShlNUW,
3854 IsLhsShlNSW && IsRhsShlNSW);
3879 return std::nullopt;
3882 Value *Original =
nullptr;
3883 const APInt *Mask =
nullptr;
3884 const APInt *MulConst =
nullptr;
3887 if (MulConst->
isZero() || Mask->isZero())
3888 return std::nullopt;
3890 return std::optional<DecomposedBitMaskMul>(
3891 {Original, *MulConst, *Mask,
3897 const APInt *EqZero =
nullptr, *NeZero =
nullptr;
3901 auto ICmpDecompose =
3904 if (!ICmpDecompose.has_value())
3905 return std::nullopt;
3908 ICmpDecompose->C.isZero());
3913 if (!EqZero->
isZero() || NeZero->isZero())
3914 return std::nullopt;
3916 if (!ICmpDecompose->Mask.isPowerOf2() || ICmpDecompose->Mask.isZero() ||
3917 NeZero->getBitWidth() != ICmpDecompose->Mask.getBitWidth())
3918 return std::nullopt;
3920 if (!NeZero->urem(ICmpDecompose->Mask).isZero())
3921 return std::nullopt;
3923 return std::optional<DecomposedBitMaskMul>(
3924 {ICmpDecompose->X, NeZero->udiv(ICmpDecompose->Mask),
3925 ICmpDecompose->Mask,
false,
false});
3928 return std::nullopt;
3944 if (Decomp0->isCombineableWith(*Decomp1)) {
3945 Value *NewAnd = Builder.CreateAnd(
3947 ConstantInt::get(Decomp0->X->getType(), Decomp0->Mask + Decomp1->Mask));
3949 return Builder.CreateMul(
3950 NewAnd, ConstantInt::get(NewAnd->
getType(), Decomp1->Factor),
"",
3951 Decomp0->NUW && Decomp1->NUW, Decomp0->NSW && Decomp1->NSW);
3970 if (
Value *Res = foldDisjointOr(
LHS,
X))
3971 return Builder.CreateOr(Res,
Y,
"",
true);
3972 if (
Value *Res = foldDisjointOr(
LHS,
Y))
3973 return Builder.CreateOr(Res,
X,
"",
true);
3977 if (
Value *Res = foldDisjointOr(
X,
RHS))
3978 return Builder.CreateOr(Res,
Y,
"",
true);
3979 if (
Value *Res = foldDisjointOr(
Y,
RHS))
3980 return Builder.CreateOr(Res,
X,
"",
true);
3994 const APInt *C1, *C2;
4003 Constant *NewC = ConstantInt::get(
X->getType(), C2->
udiv(*C1));
4024 return Builder.CreateBinaryIntrinsic(Intrinsic::abs,
X,
4025 Builder.getFalse());
4043 bool MayNeedFreeze = SelOp0 && SelOp1 &&
4044 match(SelOp1->getTrueValue(),
4049 Value *C2 =
nullptr, *A2 =
nullptr, *B2 =
nullptr;
4058 return createSelectInstWithUnknownProfile(
C,
A,
B);
4074 bool MayNeedFreeze = SelOp0 && SelOp1 &&
4075 match(SelOp0->getTrueValue(),
4080 Value *C2 =
nullptr, *A2 =
nullptr, *B2 =
nullptr;
4089 return createSelectInstWithUnknownProfile(
C,
B,
A);
4103 SQ.getWithInstruction(&
I)))
4139 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
4140 Type *Ty =
I.getType();
4141 if (Ty->isIntOrIntVectorTy(1)) {
4144 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
false))
4149 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
false))
4186 if (
Value *Res = foldDisjointOr(
I.getOperand(0),
I.getOperand(1)))
4189 if (
Value *Res = reassociateDisjointOr(
I.getOperand(0),
I.getOperand(1)))
4200 return BinaryOperator::CreateXor(
Or, ConstantInt::get(Ty, *CV));
4207 Value *IncrementY =
Builder.CreateAdd(
Y, ConstantInt::get(Ty, 1));
4208 return BinaryOperator::CreateMul(
X, IncrementY);
4215 if (
I.getType()->isIntOrIntVectorTy(1) &&
4228 const APInt *C0, *C1;
4234 return BinaryOperator::CreateOr(
Builder.CreateAnd(
X, *C0),
B);
4237 return BinaryOperator::CreateOr(
Builder.CreateAnd(
X, *C1),
A);
4241 return BinaryOperator::CreateXor(
Builder.CreateAnd(
X, *C0),
B);
4244 return BinaryOperator::CreateXor(
Builder.CreateAnd(
X, *C1),
A);
4247 if ((*C0 & *C1).
isZero()) {
4252 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
4253 return BinaryOperator::CreateAnd(
A, C01);
4259 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
4260 return BinaryOperator::CreateAnd(
B, C01);
4264 const APInt *C2, *C3;
4269 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
4270 return BinaryOperator::CreateAnd(
Or, C01);
4280 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D))
4282 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B))
4284 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D))
4286 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B))
4288 if (
Value *V = matchSelectFromAndOr(
B,
D,
A,
C))
4290 if (
Value *V = matchSelectFromAndOr(
B,
D,
C,
A))
4292 if (
Value *V = matchSelectFromAndOr(
D,
B,
A,
C))
4294 if (
Value *V = matchSelectFromAndOr(
D,
B,
C,
A))
4303 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D,
true))
4305 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B,
true))
4307 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D,
true))
4309 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B,
true))
4318 return BinaryOperator::CreateOr(Op0,
C);
4325 return BinaryOperator::CreateOr(Op1,
C);
4331 bool SwappedForXor =
false;
4334 SwappedForXor =
true;
4341 return BinaryOperator::CreateOr(Op0,
B);
4343 return BinaryOperator::CreateOr(Op0,
A);
4348 return BinaryOperator::CreateOr(
A,
B);
4376 return BinaryOperator::CreateOr(Nand,
C);
4384 foldBooleanAndOr(Op0, Op1,
I,
false,
false))
4389 if (
auto *V = reassociateBooleanAndOr(Op0,
X,
Y,
I,
false,
4395 if (
auto *V = reassociateBooleanAndOr(Op1,
X,
Y,
I,
false,
4415 A->getType()->isIntOrIntVectorTy(1))
4416 return createSelectInstWithUnknownProfile(
4438 return IsDisjointOuter && IsDisjointInner
4439 ? BinaryOperator::CreateDisjointOr(Inner, CI)
4440 : BinaryOperator::CreateOr(Inner, CI);
4447 Value *
X =
nullptr, *
Y =
nullptr;
4466 return createSelectInstWithUnknownProfile(NewICmpInst,
AllOnes,
X);
4479 return BinaryOperator::CreateXor(
A,
B);
4495 Value *
Mul, *Ov, *MulIsNotZero, *UMulWithOv;
4513 return BinaryOperator::CreateAnd(NotNullA, NotNullB);
4522 const APInt *C1, *C2;
4537 : C2->
uadd_ov(*C1, Overflow));
4541 return BinaryOperator::CreateOr(Ov, NewCmp);
4560 ConstantInt::get(Ty, Ty->getScalarSizeInBits() - 1),
X);
4566 Value *Start =
nullptr, *Step =
nullptr;
4584 return BinaryOperator::CreateOr(
4596 return BinaryOperator::CreateOr(
4604 return Canonicalized;
4606 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
4626 !
Builder.GetInsertBlock()->getParent()->hasFnAttribute(
4627 Attribute::NoImplicitFloat)) {
4631 Value *FAbs =
Builder.CreateUnaryIntrinsic(Intrinsic::fabs, CastOp);
4641 if ((KnownX.
One & *C2) == *C2)
4642 return BinaryOperator::CreateAnd(
X, ConstantInt::get(Ty, *C1 | *C2));
4651 return BinaryOperator::CreateOr(V, Op1);
4655 return BinaryOperator::CreateOr(Op0, V);
4671 assert(
I.getOpcode() == Instruction::Xor);
4672 Value *Op0 =
I.getOperand(0);
4673 Value *Op1 =
I.getOperand(1);
4684 return BinaryOperator::CreateXor(
A,
B);
4692 return BinaryOperator::CreateXor(
A,
B);
4700 return BinaryOperator::CreateXor(
A,
B);
4722 assert(
I.getOpcode() == Instruction::Xor &&
I.getOperand(0) ==
LHS &&
4723 I.getOperand(1) ==
RHS &&
"Should be 'xor' with these operands");
4726 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
4727 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
4730 if (LHS0 == RHS1 && LHS1 == RHS0) {
4734 if (LHS0 == RHS0 && LHS1 == RHS1) {
4737 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
4742 const APInt *LC, *RC;
4751 bool TrueIfSignedL, TrueIfSignedR;
4756 return TrueIfSignedL == TrueIfSignedR ?
Builder.CreateIsNeg(XorLR) :
4757 Builder.CreateIsNotNeg(XorLR);
4767 if (CRUnion && CRIntersect)
4768 if (
auto CR = CRUnion->exactIntersectWith(CRIntersect->inverse())) {
4769 if (CR->isFullSet())
4771 if (CR->isEmptySet())
4776 CR->getEquivalentICmp(NewPred, NewC,
Offset);
4783 NewV =
Builder.CreateAdd(NewV, ConstantInt::get(Ty,
Offset));
4784 return Builder.CreateICmp(NewPred, NewV,
4785 ConstantInt::get(Ty, NewC));
4817 ICmpInst *
X =
nullptr, *
Y =
nullptr;
4818 if (OrICmp ==
LHS && AndICmp ==
RHS) {
4823 if (OrICmp ==
RHS && AndICmp ==
LHS) {
4830 Y->setPredicate(
Y->getInversePredicate());
4832 if (!
Y->hasOneUse()) {
4839 Builder.SetInsertPoint(
Y->getParent(), ++(
Y->getIterator()));
4843 Y->replaceUsesWithIf(NotY,
4844 [NotY](Use &U) {
return U.getUser() != NotY; });
4882 Value *NewA = Builder.CreateAnd(
D, NotM);
4883 return BinaryOperator::CreateXor(NewA,
X);
4889 Type *EltTy =
C->getType()->getScalarType();
4893 Value *NotC = Builder.CreateNot(
C);
4894 Value *
RHS = Builder.CreateAnd(
B, NotC);
4895 return BinaryOperator::CreateOr(
LHS,
RHS);
4910 return A ==
C ||
A ==
D ||
B ==
C ||
B ==
D;
4918 Value *NotY = Builder.CreateNot(
Y);
4919 return BinaryOperator::CreateOr(
X, NotY);
4926 Value *NotX = Builder.CreateNot(
X);
4927 return BinaryOperator::CreateOr(
Y, NotX);
4937 assert(
Xor.getOpcode() == Instruction::Xor &&
"Expected an xor instruction.");
4943 Value *Op0 =
Xor.getOperand(0), *Op1 =
Xor.getOperand(1);
4951 Op1->
hasNUses(2) && *ShAmt == Ty->getScalarSizeInBits() - 1 &&
4956 Value *IsNeg = Builder.CreateIsNeg(
A);
4959 Value *NegA =
Add->hasNoUnsignedWrap()
4961 : Builder.CreateNeg(
A,
"",
Add->hasNoSignedWrap());
4979 Op->replaceUsesWithIf(NotOp,
4980 [NotOp](
Use &U) {
return U.getUser() != NotOp; });
5021 Builder.SetInsertPoint(*
I.getInsertionPointAfterDef());
5024 NewLogicOp =
Builder.CreateBinOp(NewOpc, Op0, Op1,
I.getName() +
".not");
5027 Builder.CreateLogicalOp(NewOpc, Op0, Op1,
I.getName() +
".not",
5030 SI->swapProfMetadata();
5054 Value *NotOp0 =
nullptr;
5055 Value *NotOp1 =
nullptr;
5056 Value **OpToInvert =
nullptr;
5073 Builder.SetInsertPoint(*
I.getInsertionPointAfterDef());
5076 NewBinOp =
Builder.CreateBinOp(NewOpc, Op0, Op1,
I.getName() +
".not");
5078 NewBinOp =
Builder.CreateLogicalOp(NewOpc, Op0, Op1,
I.getName() +
".not");
5101 Type *Ty =
I.getType();
5104 Value *NotY = Builder.CreateNot(
Y,
Y->getName() +
".not");
5105 return BinaryOperator::CreateOr(
X, NotY);
5108 Value *NotY = Builder.CreateNot(
Y,
Y->getName() +
".not");
5112 SI->swapProfMetadata();
5120 return BinaryOperator::CreateAnd(
X, NotY);
5127 SI->swapProfMetadata();
5132 BinaryOperator *NotVal;
5139 return BinaryOperator::CreateAnd(DecX, NotY);
5144 return BinaryOperator::CreateAShr(
X,
Y);
5150 return BinaryOperator::CreateAShr(
X,
Y);
5157 return new SExtInst(IsNotNeg, Ty);
5184 return BinaryOperator::CreateAdd(
Builder.CreateNot(
X),
Y);
5207 return new BitCastInst(
X, Ty);
5213 X->getType()->isIntOrIntVectorTy(1)) {
5217 return new BitCastInst(Sext, Ty);
5228 if (
II &&
II->hasOneUse()) {
5232 Value *InvMaxMin =
Builder.CreateBinaryIntrinsic(InvID,
X, NotY);
5236 if (
II->getIntrinsicID() == Intrinsic::is_fpclass) {
5239 1, ConstantInt::get(ClassMask->
getType(),
5255 Value *TV = Sel->getTrueValue();
5256 Value *FV = Sel->getFalseValue();
5259 bool InvertibleT = (CmpT && CmpT->hasOneUse()) ||
isa<Constant>(TV);
5260 bool InvertibleF = (CmpF && CmpF->hasOneUse()) ||
isa<Constant>(FV);
5261 if (InvertibleT && InvertibleF) {
5263 CmpT->setPredicate(CmpT->getInversePredicate());
5267 CmpF->setPredicate(CmpF->getInversePredicate());
5298 Value *NotC = Builder.CreateNot(AddC);
5301 return BinaryOperator::CreateAnd(NewSub, Mask);
5312 SQ.getWithInstruction(&
I)))
5342 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
5350 return BinaryOperator::CreateXor(XorAC,
Y);
5353 return BinaryOperator::CreateXor(XorBC,
X);
5363 return BinaryOperator::CreateDisjointOr(Op0, Op1);
5365 return BinaryOperator::CreateOr(Op0, Op1);
5382 return BinaryOperator::CreateXor(
5405 *CA ==
X->getType()->getScalarSizeInBits() - 1 &&
5409 return createSelectInstWithUnknownProfile(IsNotNeg, Op1,
5414 Type *Ty =
I.getType();
5422 return BinaryOperator::CreateSub(ConstantInt::get(Ty, *
C + *RHSC),
X);
5426 return BinaryOperator::CreateAdd(
X, ConstantInt::get(Ty, *
C + *RHSC));
5431 return BinaryOperator::CreateXor(
X, ConstantInt::get(Ty, *
C ^ *RHSC));
5437 if (
II &&
II->hasOneUse() && *RHSC == Ty->getScalarSizeInBits() - 1) {
5439 if ((IID == Intrinsic::ctlz || IID == Intrinsic::cttz) &&
5442 IID = (IID == Intrinsic::ctlz) ? Intrinsic::cttz : Intrinsic::ctlz;
5455 return BinaryOperator::CreateShl(NotX, ConstantInt::get(Ty, *
C));
5461 return BinaryOperator::CreateLShr(NotX, ConstantInt::get(Ty, *
C));
5479 !
Builder.GetInsertBlock()->getParent()->hasFnAttribute(
5480 Attribute::NoImplicitFloat)) {
5503 auto *Opnd0 =
Builder.CreateLShr(
X, C2);
5504 Opnd0->takeName(Op0);
5505 return BinaryOperator::CreateXor(Opnd0, ConstantInt::get(Ty, FoldConst));
5518 return BinaryOperator::CreateAnd(
X,
Builder.CreateNot(Op0));
5522 return BinaryOperator::CreateAnd(
X,
Builder.CreateNot(Op1));
5527 return BinaryOperator::CreateAnd(Op0,
Builder.CreateNot(
X));
5535 return BinaryOperator::CreateAnd(Op1,
Builder.CreateNot(
X));
5541 return BinaryOperator::CreateXor(
5547 return BinaryOperator::CreateXor(
5553 return BinaryOperator::CreateOr(
A,
B);
5557 return BinaryOperator::CreateOr(
A,
B);
5567 return BinaryOperator::CreateOr(
A,
B);
5582 if (
B ==
C ||
B ==
D)
5588 return BinaryOperator::CreateAnd(
Builder.CreateXor(
B,
C), NotA);
5593 if (
I.getType()->isIntOrIntVectorTy(1) &&
5598 if (
B ==
C ||
B ==
D) {
5609 ? createSelectInstWithUnknownProfile(
A, NotB,
C)
5616 if (
Value *V = foldXorOfICmps(LHS, RHS,
I))
5619 if (
Instruction *CastedXor = foldCastedBitwiseLogic(
I))
5632 return BinaryOperator::CreateXor(
Builder.CreateXor(
X,
Y), C1);
5638 return Canonicalized;
5640 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
5643 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< 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 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 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 TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
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.
ArrayRef - 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 Constant * getZero(Type *Ty, bool Negative=false)
This is the shared class of boolean and integer constants.
bool isMinusOne() const
This function will return true iff every bit in this constant is set to true.
static 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...
LLVM_ABI bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
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.
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
IRBuilder< TargetFolder, IRBuilderCallbackInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
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...
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.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
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)
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
cst_pred_ty< is_lowbit_mask > m_LowBitMask()
Match an integer or vector with only the low bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
cst_pred_ty< is_negative > m_Negative()
Match an integer or vector of negative values.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
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.
m_Intrinsic_Ty< Opnd0 >::Ty m_BitReverse(const Opnd0 &Op0)
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power-of-2.
match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)
auto m_LogicalOp()
Matches either L && R or L || R where L and R are arbitrary values.
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
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.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWSub(const LHS &L, const RHS &R)
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
match_combine_or< CastInst_match< OpTy, ZExtInst >, OpTy > m_ZExtOrSelf(const OpTy &Op)
bool match(Val *V, const Pattern &P)
cst_pred_ty< is_shifted_mask > m_ShiftedMask()
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
DisjointOr_match< LHS, RHS > m_DisjointOr(const LHS &L, const RHS &R)
constantexpr_match m_ConstantExpr()
Match a constant expression or a constant that contains a constant expression.
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.
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
match_combine_or< CastInst_match< OpTy, SExtInst >, OpTy > m_SExtOrSelf(const OpTy &Op)
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.
match_combine_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)
Combine two pattern matchers matching L && R.
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).
bind_ty< WithOverflowInst > m_WithOverflowInst(WithOverflowInst *&I)
Match a with overflow intrinsic, capturing it if we match.
BinaryOp_match< LHS, RHS, Instruction::Xor, true > m_c_Xor(const LHS &L, const RHS &R)
Matches an Xor with LHS and RHS in either order.
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)
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
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.
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.
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
cst_pred_ty< is_negated_power2 > m_NegatedPower2()
Match a integer or vector negated power-of-2.
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< match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty, true >, MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty, true > >, match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty, true >, MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty, true > > > m_c_MaxOrMin(const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, SExtInst >, NNegZExt_match< OpTy > > m_SExtLike(const OpTy &Op)
Match either "sext" or "zext nneg".
MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty > m_SMax(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....
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
AnyBinaryOp_match< LHS, RHS, true > m_c_BinOp(const LHS &L, const RHS &R)
Matches a BinaryOperator with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
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.
cstfp_pred_ty< is_pos_zero_fp > m_PosZeroFP()
Match a floating-point positive zero.
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)
m_Intrinsic_Ty< Opnd0 >::Ty m_BSwap(const Opnd0 &Op0)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
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)
match_unless< Ty > m_Unless(const Ty &M)
Match if the inner matcher does NOT match.
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
cst_pred_ty< icmp_pred_with_threshold > m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold)
Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.
NodeAddr< CodeNode * > Code
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.
FunctionAddr VTableAddr Value
Constant * getPredForFCmpCode(unsigned Code, Type *OpTy, CmpInst::Predicate &Pred)
This is the complement of getFCmpCode.
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.
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.
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.
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.
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.
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.
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.
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)
bool isNonNegative() const
Returns true if this value is known to be non-negative.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
SimplifyQuery getWithInstruction(const Instruction *I) const