23using namespace PatternMatch;
25#define DEBUG_TYPE "instcombine"
56 assert(
I.isBitwiseLogicOp() &&
"Unexpected opcode for bswap simplifying");
58 Value *OldLHS =
I.getOperand(0);
59 Value *OldRHS =
I.getOperand(1);
81 Value *BinOp =
Builder.CreateBinOp(
I.getOpcode(), NewLHS, NewRHS);
94 "Lo is not < Hi in range emission code!");
96 Type *Ty = V->getType();
101 if (
isSigned ?
Lo.isMinSignedValue() :
Lo.isMinValue()) {
158 const APInt *ConstA =
nullptr, *ConstB =
nullptr, *ConstC =
nullptr;
163 bool IsAPow2 = ConstA && ConstA->
isPowerOf2();
164 bool IsBPow2 = ConstB && ConstB->isPowerOf2();
165 unsigned MaskVal = 0;
166 if (ConstC && ConstC->isZero()) {
185 }
else if (ConstA && ConstC && ConstC->
isSubsetOf(*ConstA)) {
195 }
else if (ConstB && ConstC && ConstC->isSubsetOf(*ConstB)) {
252 Value *L11, *L12, *L21, *L22;
255 L21 = L22 = L1 =
nullptr;
280 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
283 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
300 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
305 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
324 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
329 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
338 assert(Ok &&
"Failed to find AND on the right side of the RHS icmp.");
344 }
else if (L12 ==
A) {
347 }
else if (L21 ==
A) {
350 }
else if (L22 ==
A) {
357 return std::optional<std::pair<unsigned, unsigned>>(
358 std::make_pair(LeftType, RightType));
380 const APInt *BCst, *CCst, *DCst, *OrigECst;
391 APInt ECst = *OrigECst;
397 if (*BCst == 0 || *DCst == 0)
404 if ((*BCst & *DCst) == 0)
423 if ((((*BCst & *DCst) & ECst) == 0) &&
424 (*BCst & (*BCst ^ *DCst)).isPowerOf2()) {
425 APInt BorD = *BCst | *DCst;
426 APInt BandBxorDorE = (*BCst & (*BCst ^ *DCst)) | ECst;
430 return Builder.CreateICmp(NewCC, NewAnd, NewMaskedValue);
433 auto IsSubSetOrEqual = [](
const APInt *C1,
const APInt *C2) {
434 return (*C1 & *C2) == *C1;
436 auto IsSuperSetOrEqual = [](
const APInt *C1,
const APInt *C2) {
437 return (*C1 & *C2) == *C2;
446 if (!IsSubSetOrEqual(BCst, DCst) && !IsSuperSetOrEqual(BCst, DCst))
458 if (IsSubSetOrEqual(BCst, DCst))
469 if (IsSuperSetOrEqual(BCst, DCst))
474 assert(IsSubSetOrEqual(BCst, DCst) &&
"Precondition due to above code");
475 if ((*BCst & ECst) != 0)
493 "Expected equality predicates for masked type of icmps.");
524 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *
E =
nullptr;
526 std::optional<std::pair<unsigned, unsigned>> MaskPair =
531 "Expected equality predicates for masked type of icmps.");
532 unsigned LHSMask = MaskPair->first;
533 unsigned RHSMask = MaskPair->second;
534 unsigned Mask = LHSMask & RHSMask;
539 LHS,
RHS, IsAnd,
A,
B,
C,
D,
E, PredL, PredR, LHSMask, RHSMask,
575 return Builder.CreateICmp(NewCC, NewAnd, Zero);
584 return Builder.CreateICmp(NewCC, NewAnd, NewOr);
593 return Builder.CreateICmp(NewCC, NewAnd2,
A);
599 const APInt *ConstB, *ConstD;
609 APInt NewMask = *ConstB & *ConstD;
610 if (NewMask == *ConstB)
612 else if (NewMask == *ConstD)
621 APInt NewMask = *ConstB | *ConstD;
622 if (NewMask == *ConstB)
624 else if (NewMask == *ConstD)
651 const APInt *OldConstC, *OldConstE;
657 const APInt ConstC = PredL !=
CC ? *ConstB ^ *OldConstC : *OldConstC;
658 const APInt ConstE = PredR !=
CC ? *ConstD ^ *OldConstE : *OldConstE;
660 if (((*ConstB & *ConstD) & (ConstC ^ ConstE)).getBoolValue())
663 if (IsNot && !ConstB->
isSubsetOf(*ConstD) && !ConstD->isSubsetOf(*ConstB))
668 BD = *ConstB & *ConstD;
669 CE = ConstC & ConstE;
671 BD = *ConstB | *ConstD;
672 CE = ConstC | ConstE;
676 return Builder.CreateICmp(
CC, CEVal, NewAnd);
680 return FoldBMixed(NewCC,
false);
682 return FoldBMixed(NewCC,
true);
728 default:
return nullptr;
744Value *InstCombinerImpl::foldAndOrOfICmpsOfAndWithPow2(
ICmpInst *LHS,
750 if (
LHS->getPredicate() != Pred ||
RHS->getPredicate() != Pred)
760 if (L1 ==
R2 || L2 ==
R2)
818 auto tryToMatchSignedTruncationCheck = [](
ICmpInst *ICmp,
Value *&
X,
819 APInt &SignBitMask) ->
bool {
821 const APInt *I01, *I1;
836 if (tryToMatchSignedTruncationCheck(ICmp1, X1, HighestBit))
838 else if (tryToMatchSignedTruncationCheck(ICmp0, X1, HighestBit))
843 assert(HighestBit.
isPowerOf2() &&
"expected to be power of two (non-zero)");
847 APInt &UnsetBitsMask) ->
bool {
851 Pred,
X, UnsetBitsMask,
859 UnsetBitsMask = *Mask;
868 if (!tryToDecompose(OtherICmp, X0, UnsetBitsMask))
871 assert(!UnsetBitsMask.
isZero() &&
"empty mask makes no sense.");
886 APInt SignBitsMask = ~(HighestBit - 1U);
893 if (!UnsetBitsMask.
isSubsetOf(SignBitsMask)) {
894 APInt OtherHighestBit = (~UnsetBitsMask) + 1U;
903 CxtI.
getName() +
".simplified");
970 auto IsKnownNonZero = [&](
Value *V) {
977 if (
match(UnsignedICmp,
982 if (!IsKnownNonZero(NonZero))
984 return IsKnownNonZero(NonZero);
993 IsAnd && GetKnownNonZeroAndOther(
B,
A))
996 !IsAnd && GetKnownNonZeroAndOther(
B,
A))
1004 if (!
match(UnsignedICmp,
1046 return std::nullopt;
1048 unsigned NumOriginalBits =
X->getType()->getScalarSizeInBits();
1049 unsigned NumExtractedBits = V->getType()->getScalarSizeInBits();
1055 Shift->
ule(NumOriginalBits - NumExtractedBits))
1057 return {{
X, 0, NumExtractedBits}};
1064 V =
Builder.CreateLShr(V,
P.StartBit);
1065 Type *TruncTy = V->getType()->getWithNewBitWidth(
P.NumBits);
1066 if (TruncTy != V->getType())
1067 V =
Builder.CreateTrunc(V, TruncTy);
1087 if (!L0 || !R0 || !L1 || !R1)
1092 if (L0->From != L1->From || R0->From != R1->From) {
1093 if (L0->From != R1->From || R0->From != L1->From)
1100 if (L0->StartBit + L0->NumBits != L1->StartBit ||
1101 R0->StartBit + R0->NumBits != R1->StartBit) {
1102 if (L1->StartBit + L1->NumBits != L0->StartBit ||
1103 R1->StartBit + R1->NumBits != R0->StartBit)
1110 IntPart L = {L0->From, L0->StartBit, L0->NumBits + L1->NumBits};
1111 IntPart R = {R0->From, R0->StartBit, R0->NumBits + R1->NumBits};
1121 bool IsAnd,
bool IsLogical,
1150 if (!SubstituteCmp) {
1155 SubstituteCmp =
Builder.CreateICmp(Pred1,
Y,
C);
1158 return IsAnd ?
Builder.CreateLogicalAnd(Cmp0, SubstituteCmp)
1159 :
Builder.CreateLogicalOr(Cmp0, SubstituteCmp);
1160 return Builder.CreateBinOp(IsAnd ? Instruction::And : Instruction::Or, Cmp0,
1168Value *InstCombinerImpl::foldAndOrOfICmpsUsingRanges(
ICmpInst *ICmp1,
1173 const APInt *C1, *C2;
1180 const APInt *Offset1 =
nullptr, *Offset2 =
nullptr;
1215 if (!LowerDiff.
isPowerOf2() || LowerDiff != UpperDiff ||
1228 CR->getEquivalentICmp(NewPred, NewC,
Offset);
1260 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1261 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1270 FMF &=
RHS->getFastMathFlags();
1271 Builder.setFastMathFlags(FMF);
1277 bool IsAnd,
bool IsLogicalSelect) {
1278 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1279 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1282 if (LHS0 == RHS1 && RHS0 == LHS1) {
1302 if (LHS0 == RHS0 && LHS1 == RHS1) {
1305 unsigned NewPred = IsAnd ? FCmpCodeL & FCmpCodeR : FCmpCodeL | FCmpCodeR;
1311 FMF &=
RHS->getFastMathFlags();
1318 if (!IsLogicalSelect &&
1349 auto [ClassValRHS, ClassMaskRHS] =
1352 auto [ClassValLHS, ClassMaskLHS] =
1354 if (ClassValLHS == ClassValRHS) {
1355 unsigned CombinedMask = IsAnd ? (ClassMaskLHS & ClassMaskRHS)
1356 : (ClassMaskLHS | ClassMaskRHS);
1358 Intrinsic::is_fpclass, {ClassValLHS->getType()},
1371 auto *FCmp = dyn_cast<FCmpInst>(Op);
1372 if (!FCmp || !FCmp->hasOneUse())
1375 std::tie(ClassVal, ClassMask) =
1376 fcmpToClassTest(FCmp->getPredicate(), *FCmp->getParent()->getParent(),
1377 FCmp->getOperand(0), FCmp->getOperand(1));
1378 return ClassVal !=
nullptr;
1389 Value *ClassVal0 =
nullptr;
1390 Value *ClassVal1 =
nullptr;
1407 ClassVal0 == ClassVal1) {
1408 unsigned NewClassMask;
1410 case Instruction::And:
1411 NewClassMask = ClassMask0 & ClassMask1;
1413 case Instruction::Or:
1414 NewClassMask = ClassMask0 | ClassMask1;
1416 case Instruction::Xor:
1417 NewClassMask = ClassMask0 ^ ClassMask1;
1424 auto *II = cast<IntrinsicInst>(Op0);
1431 auto *II = cast<IntrinsicInst>(Op1);
1453Instruction *InstCombinerImpl::canonicalizeConditionalNegationViaMathToSelect(
1455 assert(
I.getOpcode() == BinaryOperator::Xor &&
"Only for xor!");
1460 !
Cond->getType()->isIntOrIntVectorTy(1) ||
1474 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1475 "Expecting and/or op for fcmp transform");
1495 Pred != NanPred ||
X->getType() !=
Y->getType())
1499 Pred != NanPred ||
X->getType() !=
Y->getType())
1505 if (
auto *NewFCmpInst = dyn_cast<FCmpInst>(NewFCmp)) {
1507 NewFCmpInst->copyIRFlags(Op0);
1508 NewFCmpInst->andIRFlags(BO10);
1519 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1520 "Trying to match De Morgan's Laws with something other than and/or");
1524 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1526 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1533 Builder.CreateBinOp(FlippedOpcode,
A,
B,
I.getName() +
".demorgan");
1552bool InstCombinerImpl::shouldOptimizeCast(
CastInst *CI) {
1561 if (
const auto *PrecedingCI = dyn_cast<CastInst>(CastSrc))
1562 if (isEliminableCastPair(PrecedingCI, CI))
1587 if (ZextTruncC ==
C) {
1590 return new ZExtInst(NewOp, DestTy);
1597 if (SextTruncC ==
C) {
1600 return new SExtInst(NewOp, DestTy);
1609 auto LogicOpc =
I.getOpcode();
1610 assert(
I.isBitwiseLogicOp() &&
"Unexpected opcode for bitwise logic folding");
1612 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1613 CastInst *Cast0 = dyn_cast<CastInst>(Op0);
1619 Type *DestTy =
I.getType();
1627 CastInst *Cast1 = dyn_cast<CastInst>(Op1);
1644 unsigned XNumBits =
X->getType()->getScalarSizeInBits();
1645 unsigned YNumBits =
Y->getType()->getScalarSizeInBits();
1646 if (XNumBits < YNumBits)
1664 shouldOptimizeCast(Cast0) && shouldOptimizeCast(Cast1)) {
1671 if (LogicOpc == Instruction::Xor)
1676 ICmpInst *ICmp0 = dyn_cast<ICmpInst>(Cast0Src);
1677 ICmpInst *ICmp1 = dyn_cast<ICmpInst>(Cast1Src);
1678 if (ICmp0 && ICmp1) {
1680 foldAndOrOfICmps(ICmp0, ICmp1,
I, LogicOpc == Instruction::And))
1687 FCmpInst *FCmp0 = dyn_cast<FCmpInst>(Cast0Src);
1688 FCmpInst *FCmp1 = dyn_cast<FCmpInst>(Cast1Src);
1690 if (
Value *R = foldLogicOfFCmps(FCmp0, FCmp1, LogicOpc == Instruction::And))
1698 assert(
I.getOpcode() == Instruction::And);
1699 Value *Op0 =
I.getOperand(0);
1700 Value *Op1 =
I.getOperand(1);
1708 return BinaryOperator::CreateXor(
A,
B);
1724 assert(
I.getOpcode() == Instruction::Or);
1725 Value *Op0 =
I.getOperand(0);
1726 Value *Op1 =
I.getOperand(1);
1751 return BinaryOperator::CreateXor(
A,
B);
1771 Value *Op0 =
And.getOperand(0), *Op1 =
And.getOperand(1);
1785 if (!isa<VectorType>(Ty) && !shouldChangeType(Ty,
X->getType()))
1792 if (Opc == Instruction::LShr || Opc == Instruction::Shl)
1809 assert(Opcode == Instruction::And || Opcode == Instruction::Or);
1813 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1815 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1822 const auto matchNotOrAnd =
1823 [Opcode, FlippedOpcode](
Value *Op,
auto m_A,
auto m_B,
auto m_C,
1824 Value *&
X,
bool CountUses =
false) ->
bool {
1825 if (CountUses && !Op->hasOneUse())
1832 return !CountUses ||
X->hasOneUse();
1848 return (Opcode == Instruction::Or)
1849 ? BinaryOperator::CreateAnd(
Xor,
Builder.CreateNot(
A))
1858 return (Opcode == Instruction::Or)
1859 ? BinaryOperator::CreateAnd(
Xor,
Builder.CreateNot(
B))
1868 Opcode,
Builder.CreateBinOp(FlippedOpcode,
B,
C),
A));
1875 Opcode,
Builder.CreateBinOp(FlippedOpcode,
A,
C),
B));
1881 if (Opcode == Instruction::Or && Op0->
hasOneUse() &&
1888 Value *
Or = cast<BinaryOperator>(
X)->getOperand(0);
1920 return (Opcode == Instruction::Or)
1922 : BinaryOperator::CreateOr(
Xor,
X);
1956 if (!isa<Constant>(
X) && !isa<Constant>(
Y) && !isa<Constant>(Z)) {
1958 if (!
X->hasOneUse()) {
1963 if (!
Y->hasOneUse()) {
1984 Type *Ty =
I.getType();
1986 Value *Op0 =
I.getOperand(0);
1987 Value *Op1 =
I.getOperand(1);
1999 case Instruction::And:
2000 if (
C->countl_one() < LastOneMath)
2003 case Instruction::Xor:
2004 case Instruction::Or:
2005 if (
C->countl_zero() < LastOneMath)
2020 Type *Ty =
I.getType();
2054 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2083 return BinaryOperator::CreateXor(
And, NewC);
2094 APInt Together = *
C & *OrC;
2101 const APInt *ShiftC;
2103 ShiftC->
ult(Width)) {
2109 return BinaryOperator::CreateLShr(Sext, ShAmtC);
2123 unsigned Ctlz =
C->countl_zero();
2125 if ((*AddC & LowMask).
isZero())
2126 return BinaryOperator::CreateAnd(
X, Op1);
2132 if (Op0->
hasOneUse() &&
C->isPowerOf2() && (*AddC & (*
C - 1)) == 0) {
2133 assert((*
C & *AddC) != 0 &&
"Expected common bit");
2135 return BinaryOperator::CreateXor(NewAnd, Op1);
2142 switch (
B->getOpcode()) {
2143 case Instruction::Xor:
2144 case Instruction::Or:
2145 case Instruction::Mul:
2146 case Instruction::Add:
2147 case Instruction::Sub:
2163 C->isIntN(
X->getType()->getScalarSizeInBits())) {
2164 unsigned XWidth =
X->getType()->getScalarSizeInBits();
2179 C->isMask(
X->getType()->getScalarSizeInBits())) {
2189 C->isMask(
X->getType()->getScalarSizeInBits())) {
2223 if (
C->isPowerOf2() &&
2226 int Log2C =
C->exactLogBase2();
2228 cast<BinaryOperator>(Op0)->getOpcode() == Instruction::Shl;
2229 int BitNum = IsShiftLeft ? Log2C - Log2ShiftC : Log2ShiftC - Log2C;
2230 assert(BitNum >= 0 &&
"Expected demanded bits to handle impossible mask");
2263 if (Cmp->isZeroValue()) {
2282 X->getType()->getScalarSizeInBits())))) {
2284 auto *SanitizedSignMask = cast<Constant>(Op1);
2292 return BinaryOperator::CreateAnd(SExt, SanitizedSignMask);
2298 if (
I.getType()->isIntOrIntVectorTy(1)) {
2299 if (
auto *SI0 = dyn_cast<SelectInst>(Op0)) {
2301 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
true))
2304 if (
auto *SI1 = dyn_cast<SelectInst>(Op1)) {
2306 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
true))
2328 return BinaryOperator::CreateAnd(Op0,
B);
2331 return BinaryOperator::CreateAnd(Op1,
B);
2351 return BinaryOperator::CreateAnd(
A,
B);
2359 return BinaryOperator::CreateAnd(
A,
B);
2388 bool IsLogical = isa<SelectInst>(Op1);
2390 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
2392 foldAndOrOfICmps(
LHS, Cmp,
I,
true, IsLogical))
2397 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
2398 if (
Value *Res = foldAndOrOfICmps(
LHS, Cmp,
I,
true,
2405 bool IsLogical = isa<SelectInst>(Op0);
2407 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
2409 foldAndOrOfICmps(Cmp,
RHS,
I,
true, IsLogical))
2414 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
2415 if (
Value *Res = foldAndOrOfICmps(Cmp,
RHS,
I,
true,
2423 if (
FCmpInst *
LHS = dyn_cast<FCmpInst>(
I.getOperand(0)))
2424 if (
FCmpInst *
RHS = dyn_cast<FCmpInst>(
I.getOperand(1)))
2425 if (
Value *Res = foldLogicOfFCmps(
LHS,
RHS,
true))
2431 if (
Instruction *CastedAnd = foldCastedBitwiseLogic(
I))
2444 A->getType()->isIntOrIntVectorTy(1))
2447 A->getType()->isIntOrIntVectorTy(1))
2454 A->getType()->isIntOrIntVectorTy(1))
2457 A->getType()->isIntOrIntVectorTy(1))
2464 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2473 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2484 Value *Start =
nullptr, *Step =
nullptr;
2492 return Canonicalized;
2494 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
2502 bool MatchBitReversals) {
2510 for (
auto *Inst : Insts)
2519 unsigned Width =
Or.getType()->getScalarSizeInBits();
2528 Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
2535 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2541 Or1->
getOpcode() == BinaryOperator::LShr &&
2542 "Illegal or(shift,shift) pair");
2546 auto matchShiftAmount = [&](
Value *L,
Value *R,
unsigned Width) ->
Value * {
2548 const APInt *LI, *RI;
2550 if (LI->
ult(Width) && RI->
ult(Width) && (*LI + *RI) == Width)
2573 if (ShVal0 != ShVal1)
2584 unsigned Mask = Width - 1;
2603 Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, Width);
2606 ShAmt = matchShiftAmount(ShAmt1, ShAmt0, Width);
2612 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
2620 assert(
Or.getOpcode() == Instruction::Or &&
"bswap requires an 'or'");
2621 Value *Op0 =
Or.getOperand(0), *Op1 =
Or.getOperand(1);
2625 if ((Width & 1) != 0)
2627 unsigned HalfWidth = Width / 2;
2630 if (!isa<ZExtInst>(Op0))
2634 Value *LowerSrc, *ShlVal, *UpperSrc;
2647 NewUpper =
Builder.CreateShl(NewUpper, HalfWidth);
2650 return Builder.CreateCall(
F, BinOp);
2655 Value *LowerBSwap, *UpperBSwap;
2658 return ConcatIntrinsicCalls(Intrinsic::bswap, UpperBSwap, LowerBSwap);
2662 Value *LowerBRev, *UpperBRev;
2665 return ConcatIntrinsicCalls(Intrinsic::bitreverse, UpperBRev, LowerBRev);
2672 unsigned NumElts = cast<FixedVectorType>(C1->
getType())->getNumElements();
2673 for (
unsigned i = 0; i != NumElts; ++i) {
2676 if (!EltC1 || !EltC2)
2695 Type *Ty =
A->getType();
2711 if (
A->getType()->isIntOrIntVectorTy()) {
2713 if (NumSignBits ==
A->getType()->getScalarSizeInBits() &&
2736 Cond->getType()->isIntOrIntVectorTy(1)) {
2762 Cond->getType()->isIntOrIntVectorTy(1) &&
2776 Value *
D,
bool InvertFalseVal) {
2779 Type *OrigType =
A->getType();
2782 if (
Value *
Cond = getSelectCondition(
A,
B, InvertFalseVal)) {
2787 Type *SelTy =
A->getType();
2788 if (
auto *VecTy = dyn_cast<VectorType>(
Cond->getType())) {
2790 unsigned Elts = VecTy->getElementCount().getKnownMinValue();
2811 bool IsAnd,
bool IsLogical,
2814 IsAnd ?
LHS->getInversePredicate() :
LHS->getPredicate();
2816 IsAnd ?
RHS->getInversePredicate() :
RHS->getPredicate();
2850 if (
Value *V = foldAndOrOfICmpsOfAndWithPow2(LHS, RHS, &
I, IsAnd, IsLogical))
2854 Value *LHS0 =
LHS->getOperand(0), *RHS0 =
RHS->getOperand(0);
2855 Value *LHS1 =
LHS->getOperand(1), *RHS1 =
RHS->getOperand(1);
2856 const APInt *LHSC =
nullptr, *RHSC =
nullptr;
2863 if (LHS0 == RHS1 && LHS1 == RHS0) {
2867 if (LHS0 == RHS0 && LHS1 == RHS1) {
2870 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
2919 if (IsAnd && !IsLogical)
2934 if (
Value *
X = foldEqOfParts(LHS, RHS, IsAnd))
2959 const APInt *AndC, *SmallC =
nullptr, *BigC =
nullptr;
2973 if (SmallC && BigC) {
2993 bool TrueIfSignedL, TrueIfSignedR;
2999 if ((TrueIfSignedL && !TrueIfSignedR &&
3002 (!TrueIfSignedL && TrueIfSignedR &&
3009 if ((TrueIfSignedL && !TrueIfSignedR &&
3012 (!TrueIfSignedL && TrueIfSignedR &&
3021 return foldAndOrOfICmpsUsingRanges(LHS, RHS, IsAnd);
3060 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
3061 Type *Ty =
I.getType();
3063 if (
auto *SI0 = dyn_cast<SelectInst>(Op0)) {
3065 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
false))
3068 if (
auto *SI1 = dyn_cast<SelectInst>(Op1)) {
3070 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
false))
3104 return BinaryOperator::CreateMul(
X, IncrementY);
3109 return BinaryOperator::CreateOr(
X,
Y);
3117 const APInt *C0, *C1;
3136 if ((*C0 & *C1).
isZero()) {
3142 return BinaryOperator::CreateAnd(
A, C01);
3149 return BinaryOperator::CreateAnd(
B, C01);
3153 const APInt *C2, *C3;
3159 return BinaryOperator::CreateAnd(
Or, C01);
3169 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D))
3171 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B))
3173 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D))
3175 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B))
3177 if (
Value *V = matchSelectFromAndOr(
B,
D,
A,
C))
3179 if (
Value *V = matchSelectFromAndOr(
B,
D,
C,
A))
3181 if (
Value *V = matchSelectFromAndOr(
D,
B,
A,
C))
3183 if (
Value *V = matchSelectFromAndOr(
D,
B,
C,
A))
3192 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D,
true))
3194 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B,
true))
3196 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D,
true))
3198 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B,
true))
3205 return BinaryOperator::CreateOr(Op0,
C);
3210 return BinaryOperator::CreateOr(Op1,
C);
3214 return BinaryOperator::CreateOr(
C, Op1);
3218 return BinaryOperator::CreateOr(Op0,
C);
3228 bool SwappedForXor =
false;
3231 SwappedForXor =
true;
3238 return BinaryOperator::CreateOr(Op0,
B);
3240 return BinaryOperator::CreateOr(Op0,
A);
3246 return BinaryOperator::CreateOr(
A,
B);
3274 return BinaryOperator::CreateOr(Nand,
C);
3281 return BinaryOperator::CreateOr(NotB, Op0);
3285 return BinaryOperator::CreateOr(NotA, Op0);
3293 if ((Op0 ==
B->getOperand(0) || Op0 ==
B->getOperand(1)) &&
3294 Op1->
hasOneUse() && (
B->getOpcode() == Instruction::Or ||
3295 B->getOpcode() == Instruction::Xor)) {
3296 Value *NotOp = Op0 ==
B->getOperand(0) ?
B->getOperand(1) :
3299 return BinaryOperator::CreateOr(Not, Op0);
3316 bool IsLogical = isa<SelectInst>(Op1);
3318 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
3320 foldAndOrOfICmps(
LHS, Cmp,
I,
false, IsLogical))
3325 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
3326 if (
Value *Res = foldAndOrOfICmps(
LHS, Cmp,
I,
false,
3333 bool IsLogical = isa<SelectInst>(Op0);
3335 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
3337 foldAndOrOfICmps(Cmp,
RHS,
I,
false, IsLogical))
3342 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
3343 if (
Value *Res = foldAndOrOfICmps(Cmp,
RHS,
I,
false,
3351 if (
FCmpInst *
LHS = dyn_cast<FCmpInst>(
I.getOperand(0)))
3352 if (
FCmpInst *
RHS = dyn_cast<FCmpInst>(
I.getOperand(1)))
3353 if (
Value *Res = foldLogicOfFCmps(
LHS,
RHS,
false))
3371 A->getType()->isIntOrIntVectorTy(1))
3374 A->getType()->isIntOrIntVectorTy(1))
3387 return BinaryOperator::CreateOr(Inner, CI);
3394 Value *
X =
nullptr, *
Y =
nullptr;
3422 Value *
Mul, *Ov, *MulIsNotZero, *UMulWithOv;
3439 if (
match(UMulWithOv, m_Intrinsic<Intrinsic::umul_with_overflow>(
3443 return BinaryOperator::CreateAnd(NotNullA, NotNullB);
3463 Value *Start =
nullptr, *Step =
nullptr;
3481 return BinaryOperator::CreateOr(
3493 return BinaryOperator::CreateOr(
3501 return Canonicalized;
3503 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
3513 assert(
I.getOpcode() == Instruction::Xor);
3514 Value *Op0 =
I.getOperand(0);
3515 Value *Op1 =
I.getOperand(1);
3526 return BinaryOperator::CreateXor(
A,
B);
3534 return BinaryOperator::CreateXor(
A,
B);
3542 return BinaryOperator::CreateXor(
A,
B);
3564 assert(
I.getOpcode() == Instruction::Xor &&
I.getOperand(0) == LHS &&
3565 I.getOperand(1) == RHS &&
"Should be 'xor' with these operands");
3568 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
3569 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
3572 if (LHS0 == RHS1 && LHS1 == RHS0) {
3576 if (LHS0 == RHS0 && LHS1 == RHS1) {
3579 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
3587 const APInt *LC, *RC;
3597 bool TrueIfSignedL, TrueIfSignedR;
3610 const APInt *C1, *C2;
3615 if (LHS0 == RHS0 && *C1 + 2 == *C2 &&
3633 if (OrICmp == LHS && AndICmp == RHS) {
3638 if (OrICmp == RHS && AndICmp == LHS) {
3645 Y->setPredicate(
Y->getInversePredicate());
3647 if (!
Y->hasOneUse()) {
3658 Y->replaceUsesWithIf(NotY,
3659 [NotY](
Use &U) {
return U.getUser() != NotY; });
3699 return BinaryOperator::CreateXor(NewA,
X);
3705 Type *EltTy =
C->getType()->getScalarType();
3711 return BinaryOperator::CreateOr(
LHS,
RHS);
3734 return BinaryOperator::CreateXor(NotX,
Y,
I.getName() +
".demorgan");
3749 return A ==
C ||
A ==
D ||
B ==
C ||
B ==
D;