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");
967 "Expected equality predicates for masked type of icmps.");
987 const APInt *BCst, *DCst, *ECst;
990 (isa<UndefValue>(
B) ||
995 if (
const auto *BVTy = dyn_cast<VectorType>(
B->getType())) {
996 const auto *BFVTy = dyn_cast<FixedVectorType>(BVTy);
997 const auto *BConst = dyn_cast<Constant>(
B);
998 const auto *DConst = dyn_cast<Constant>(
D);
999 const auto *EConst = dyn_cast<Constant>(
E);
1001 if (!BFVTy || !BConst || !DConst || !EConst)
1004 for (
unsigned I = 0;
I != BFVTy->getNumElements(); ++
I) {
1005 const auto *BElt = BConst->getAggregateElement(
I);
1006 const auto *DElt = DConst->getAggregateElement(
I);
1007 const auto *EElt = EConst->getAggregateElement(
I);
1009 if (!BElt || !DElt || !EElt)
1011 if (!isReducible(BElt, DElt, EElt))
1016 if (!isReducible(
B,
D,
E))
1034 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *
E =
nullptr;
1040 std::optional<std::pair<unsigned, unsigned>> MaskPair =
1046 unsigned CmpMask0 = MaskPair->first;
1047 unsigned CmpMask1 = MaskPair->second;
1048 if ((CmpMask0 &
Mask_AllZeros) && (CmpMask1 == compareBMask)) {
1052 }
else if ((CmpMask0 == compareBMask) && (CmpMask1 &
Mask_AllZeros)) {
1063 ICmpInst *UnsignedICmp,
bool IsAnd,
1072 auto IsKnownNonZero = [&](
Value *V) {
1079 if (
match(UnsignedICmp,
1084 if (!IsKnownNonZero(NonZero))
1086 return IsKnownNonZero(NonZero);
1095 IsAnd && GetKnownNonZeroAndOther(
B,
A))
1098 !IsAnd && GetKnownNonZeroAndOther(
B,
A))
1106 if (!
match(UnsignedICmp,
1148 return std::nullopt;
1150 unsigned NumOriginalBits =
X->getType()->getScalarSizeInBits();
1151 unsigned NumExtractedBits = V->getType()->getScalarSizeInBits();
1157 Shift->
ule(NumOriginalBits - NumExtractedBits))
1159 return {{
X, 0, NumExtractedBits}};
1166 V =
Builder.CreateLShr(V,
P.StartBit);
1167 Type *TruncTy = V->getType()->getWithNewBitWidth(
P.NumBits);
1168 if (TruncTy != V->getType())
1169 V =
Builder.CreateTrunc(V, TruncTy);
1189 if (!L0 || !R0 || !L1 || !R1)
1194 if (L0->From != L1->From || R0->From != R1->From) {
1195 if (L0->From != R1->From || R0->From != L1->From)
1202 if (L0->StartBit + L0->NumBits != L1->StartBit ||
1203 R0->StartBit + R0->NumBits != R1->StartBit) {
1204 if (L1->StartBit + L1->NumBits != L0->StartBit ||
1205 R1->StartBit + R1->NumBits != R0->StartBit)
1212 IntPart L = {L0->From, L0->StartBit, L0->NumBits + L1->NumBits};
1213 IntPart R = {R0->From, R0->StartBit, R0->NumBits + R1->NumBits};
1223 bool IsAnd,
bool IsLogical,
1252 if (!SubstituteCmp) {
1257 SubstituteCmp =
Builder.CreateICmp(Pred1,
Y,
C);
1260 return IsAnd ?
Builder.CreateLogicalAnd(Cmp0, SubstituteCmp)
1261 :
Builder.CreateLogicalOr(Cmp0, SubstituteCmp);
1262 return Builder.CreateBinOp(IsAnd ? Instruction::And : Instruction::Or, Cmp0,
1270Value *InstCombinerImpl::foldAndOrOfICmpsUsingRanges(
ICmpInst *ICmp1,
1275 const APInt *C1, *C2;
1282 const APInt *Offset1 =
nullptr, *Offset2 =
nullptr;
1317 if (!LowerDiff.
isPowerOf2() || LowerDiff != UpperDiff ||
1330 CR->getEquivalentICmp(NewPred, NewC,
Offset);
1362 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1363 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1372 FMF &=
RHS->getFastMathFlags();
1373 Builder.setFastMathFlags(FMF);
1379 bool IsAnd,
bool IsLogicalSelect) {
1380 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1381 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1384 if (LHS0 == RHS1 && RHS0 == LHS1) {
1404 if (LHS0 == RHS0 && LHS1 == RHS1) {
1407 unsigned NewPred = IsAnd ? FCmpCodeL & FCmpCodeR : FCmpCodeL | FCmpCodeR;
1413 FMF &=
RHS->getFastMathFlags();
1420 if (!IsLogicalSelect &&
1451 auto [ClassValRHS, ClassMaskRHS] =
1454 auto [ClassValLHS, ClassMaskLHS] =
1456 if (ClassValLHS == ClassValRHS) {
1457 unsigned CombinedMask = IsAnd ? (ClassMaskLHS & ClassMaskRHS)
1458 : (ClassMaskLHS | ClassMaskRHS);
1460 Intrinsic::is_fpclass, {ClassValLHS->getType()},
1473 auto *FCmp = dyn_cast<FCmpInst>(
Op);
1474 if (!FCmp || !FCmp->hasOneUse())
1477 std::tie(ClassVal, ClassMask) =
1478 fcmpToClassTest(FCmp->getPredicate(), *FCmp->getParent()->getParent(),
1479 FCmp->getOperand(0), FCmp->getOperand(1));
1480 return ClassVal !=
nullptr;
1491 Value *ClassVal0 =
nullptr;
1492 Value *ClassVal1 =
nullptr;
1509 ClassVal0 == ClassVal1) {
1510 unsigned NewClassMask;
1512 case Instruction::And:
1513 NewClassMask = ClassMask0 & ClassMask1;
1515 case Instruction::Or:
1516 NewClassMask = ClassMask0 | ClassMask1;
1518 case Instruction::Xor:
1519 NewClassMask = ClassMask0 ^ ClassMask1;
1526 auto *II = cast<IntrinsicInst>(Op0);
1533 auto *II = cast<IntrinsicInst>(Op1);
1555Instruction *InstCombinerImpl::canonicalizeConditionalNegationViaMathToSelect(
1557 assert(
I.getOpcode() == BinaryOperator::Xor &&
"Only for xor!");
1562 !
Cond->getType()->isIntOrIntVectorTy(1) ||
1576 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1577 "Expecting and/or op for fcmp transform");
1597 Pred != NanPred ||
X->getType() !=
Y->getType())
1601 Pred != NanPred ||
X->getType() !=
Y->getType())
1607 if (
auto *NewFCmpInst = dyn_cast<FCmpInst>(NewFCmp)) {
1609 NewFCmpInst->copyIRFlags(Op0);
1610 NewFCmpInst->andIRFlags(BO10);
1621 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1622 "Trying to match De Morgan's Laws with something other than and/or");
1626 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1628 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1635 Builder.CreateBinOp(FlippedOpcode,
A,
B,
I.getName() +
".demorgan");
1654bool InstCombinerImpl::shouldOptimizeCast(
CastInst *CI) {
1663 if (
const auto *PrecedingCI = dyn_cast<CastInst>(CastSrc))
1664 if (isEliminableCastPair(PrecedingCI, CI))
1689 if (ZextTruncC ==
C) {
1692 return new ZExtInst(NewOp, DestTy);
1699 if (SextTruncC ==
C) {
1702 return new SExtInst(NewOp, DestTy);
1711 auto LogicOpc =
I.getOpcode();
1712 assert(
I.isBitwiseLogicOp() &&
"Unexpected opcode for bitwise logic folding");
1714 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1720 auto FoldBitwiseICmpZeroWithICmp = [&](
Value *Op0,
1736 auto *ICmpR = cast<ZExtInst>(Op1)->getOperand(0);
1742 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op0, Op1))
1745 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op1, Op0))
1748 CastInst *Cast0 = dyn_cast<CastInst>(Op0);
1754 Type *DestTy =
I.getType();
1762 CastInst *Cast1 = dyn_cast<CastInst>(Op1);
1779 unsigned XNumBits =
X->getType()->getScalarSizeInBits();
1780 unsigned YNumBits =
Y->getType()->getScalarSizeInBits();
1781 if (XNumBits < YNumBits)
1799 shouldOptimizeCast(Cast0) && shouldOptimizeCast(Cast1)) {
1806 if (LogicOpc == Instruction::Xor)
1811 ICmpInst *ICmp0 = dyn_cast<ICmpInst>(Cast0Src);
1812 ICmpInst *ICmp1 = dyn_cast<ICmpInst>(Cast1Src);
1813 if (ICmp0 && ICmp1) {
1815 foldAndOrOfICmps(ICmp0, ICmp1,
I, LogicOpc == Instruction::And))
1822 FCmpInst *FCmp0 = dyn_cast<FCmpInst>(Cast0Src);
1823 FCmpInst *FCmp1 = dyn_cast<FCmpInst>(Cast1Src);
1825 if (
Value *R = foldLogicOfFCmps(FCmp0, FCmp1, LogicOpc == Instruction::And))
1833 assert(
I.getOpcode() == Instruction::And);
1834 Value *Op0 =
I.getOperand(0);
1835 Value *Op1 =
I.getOperand(1);
1843 return BinaryOperator::CreateXor(
A,
B);
1859 assert(
I.getOpcode() == Instruction::Or);
1860 Value *Op0 =
I.getOperand(0);
1861 Value *Op1 =
I.getOperand(1);
1886 return BinaryOperator::CreateXor(
A,
B);
1906 Value *Op0 =
And.getOperand(0), *Op1 =
And.getOperand(1);
1920 if (!isa<VectorType>(Ty) && !shouldChangeType(Ty,
X->getType()))
1927 if (Opc == Instruction::LShr || Opc == Instruction::Shl)
1944 assert(Opcode == Instruction::And || Opcode == Instruction::Or);
1948 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1950 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1957 const auto matchNotOrAnd =
1958 [Opcode, FlippedOpcode](
Value *
Op,
auto m_A,
auto m_B,
auto m_C,
1959 Value *&
X,
bool CountUses =
false) ->
bool {
1960 if (CountUses && !
Op->hasOneUse())
1967 return !CountUses ||
X->hasOneUse();
1983 return (Opcode == Instruction::Or)
1984 ? BinaryOperator::CreateAnd(
Xor,
Builder.CreateNot(
A))
1993 return (Opcode == Instruction::Or)
1994 ? BinaryOperator::CreateAnd(
Xor,
Builder.CreateNot(
B))
2003 Opcode,
Builder.CreateBinOp(FlippedOpcode,
B,
C),
A));
2010 Opcode,
Builder.CreateBinOp(FlippedOpcode,
A,
C),
B));
2016 if (Opcode == Instruction::Or && Op0->
hasOneUse() &&
2023 Value *
Or = cast<BinaryOperator>(
X)->getOperand(0);
2055 return (Opcode == Instruction::Or)
2057 : BinaryOperator::CreateOr(
Xor,
X);
2091 if (!isa<Constant>(
X) && !isa<Constant>(
Y) && !isa<Constant>(Z)) {
2093 if (!
X->hasOneUse()) {
2098 if (!
Y->hasOneUse()) {
2119 Type *Ty =
I.getType();
2121 Value *Op0 =
I.getOperand(0);
2122 Value *Op1 =
I.getOperand(1);
2134 case Instruction::And:
2135 if (
C->countl_one() < LastOneMath)
2138 case Instruction::Xor:
2139 case Instruction::Or:
2140 if (
C->countl_zero() < LastOneMath)
2156 assert((
I.isBitwiseLogicOp() ||
I.getOpcode() == Instruction::Add) &&
2157 "Unexpected opcode");
2160 Constant *ShiftedC1, *ShiftedC2, *AddC;
2161 Type *Ty =
I.getType();
2175 auto *Op0Inst = dyn_cast<Instruction>(
I.getOperand(0));
2176 auto *Op1Inst = dyn_cast<Instruction>(
I.getOperand(1));
2177 if (!Op0Inst || !Op1Inst)
2183 if (ShiftOp != Op1Inst->getOpcode())
2187 if (
I.getOpcode() == Instruction::Add && ShiftOp != Instruction::Shl)
2199 Type *Ty =
I.getType();
2236 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2265 return BinaryOperator::CreateXor(
And, NewC);
2276 APInt Together = *
C & *OrC;
2283 const APInt *ShiftC;
2285 ShiftC->
ult(Width)) {
2291 return BinaryOperator::CreateLShr(Sext, ShAmtC);
2305 unsigned Ctlz =
C->countl_zero();
2307 if ((*AddC & LowMask).
isZero())
2308 return BinaryOperator::CreateAnd(
X, Op1);
2314 if (Op0->
hasOneUse() &&
C->isPowerOf2() && (*AddC & (*
C - 1)) == 0) {
2315 assert((*
C & *AddC) != 0 &&
"Expected common bit");
2317 return BinaryOperator::CreateXor(NewAnd, Op1);
2324 switch (
B->getOpcode()) {
2325 case Instruction::Xor:
2326 case Instruction::Or:
2327 case Instruction::Mul:
2328 case Instruction::Add:
2329 case Instruction::Sub:
2345 C->isIntN(
X->getType()->getScalarSizeInBits())) {
2346 unsigned XWidth =
X->getType()->getScalarSizeInBits();
2361 C->isMask(
X->getType()->getScalarSizeInBits())) {
2371 C->isMask(
X->getType()->getScalarSizeInBits())) {
2405 if (
C->isPowerOf2() &&
2408 int Log2C =
C->exactLogBase2();
2410 cast<BinaryOperator>(Op0)->getOpcode() == Instruction::Shl;
2411 int BitNum = IsShiftLeft ? Log2C - Log2ShiftC : Log2ShiftC - Log2C;
2412 assert(BitNum >= 0 &&
"Expected demanded bits to handle impossible mask");
2445 if (Cmp->isZeroValue()) {
2470 Attribute::NoImplicitFloat)) {
2474 I.getType()->getScalarType()->getPrimitiveSizeInBits()) {
2486 X->getType()->getScalarSizeInBits())))) {
2488 auto *SanitizedSignMask = cast<Constant>(Op1);
2496 return BinaryOperator::CreateAnd(SExt, SanitizedSignMask);
2502 if (
I.getType()->isIntOrIntVectorTy(1)) {
2503 if (
auto *SI0 = dyn_cast<SelectInst>(Op0)) {
2505 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
true))
2508 if (
auto *SI1 = dyn_cast<SelectInst>(Op1)) {
2510 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
true))
2532 return BinaryOperator::CreateAnd(Op0,
B);
2535 return BinaryOperator::CreateAnd(Op1,
B);
2555 return BinaryOperator::CreateAnd(
A,
B);
2563 return BinaryOperator::CreateAnd(
A,
B);
2592 bool IsLogical = isa<SelectInst>(Op1);
2594 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
2596 foldAndOrOfICmps(
LHS, Cmp,
I,
true, IsLogical))
2601 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
2602 if (
Value *Res = foldAndOrOfICmps(
LHS, Cmp,
I,
true,
2609 bool IsLogical = isa<SelectInst>(Op0);
2611 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
2613 foldAndOrOfICmps(Cmp,
RHS,
I,
true, IsLogical))
2618 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
2619 if (
Value *Res = foldAndOrOfICmps(Cmp,
RHS,
I,
true,
2627 if (
FCmpInst *
LHS = dyn_cast<FCmpInst>(
I.getOperand(0)))
2628 if (
FCmpInst *
RHS = dyn_cast<FCmpInst>(
I.getOperand(1)))
2629 if (
Value *Res = foldLogicOfFCmps(
LHS,
RHS,
true))
2635 if (
Instruction *CastedAnd = foldCastedBitwiseLogic(
I))
2648 A->getType()->isIntOrIntVectorTy(1))
2654 A->getType()->isIntOrIntVectorTy(1))
2660 if (
A->getType()->isIntOrIntVectorTy(1))
2673 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2682 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2693 Value *Start =
nullptr, *Step =
nullptr;
2701 return Canonicalized;
2703 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
2714 bool MatchBitReversals) {
2722 for (
auto *Inst : Insts)
2731 unsigned Width =
Or.getType()->getScalarSizeInBits();
2740 Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
2747 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2753 Or1->
getOpcode() == BinaryOperator::LShr &&
2754 "Illegal or(shift,shift) pair");
2758 auto matchShiftAmount = [&](
Value *L,
Value *R,
unsigned Width) ->
Value * {
2760 const APInt *LI, *RI;
2762 if (LI->
ult(Width) && RI->
ult(Width) && (*LI + *RI) == Width)
2785 if (ShVal0 != ShVal1)
2796 unsigned Mask = Width - 1;
2815 Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, Width);
2818 ShAmt = matchShiftAmount(ShAmt1, ShAmt0, Width);
2824 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
2832 assert(
Or.getOpcode() == Instruction::Or &&
"bswap requires an 'or'");
2833 Value *Op0 =
Or.getOperand(0), *Op1 =
Or.getOperand(1);
2837 if ((Width & 1) != 0)
2839 unsigned HalfWidth = Width / 2;
2842 if (!isa<ZExtInst>(Op0))
2846 Value *LowerSrc, *ShlVal, *UpperSrc;
2859 NewUpper =
Builder.CreateShl(NewUpper, HalfWidth);
2862 return Builder.CreateCall(
F, BinOp);
2867 Value *LowerBSwap, *UpperBSwap;
2870 return ConcatIntrinsicCalls(Intrinsic::bswap, UpperBSwap, LowerBSwap);
2874 Value *LowerBRev, *UpperBRev;
2877 return ConcatIntrinsicCalls(Intrinsic::bitreverse, UpperBRev, LowerBRev);
2884 unsigned NumElts = cast<FixedVectorType>(C1->
getType())->getNumElements();
2885 for (
unsigned i = 0; i != NumElts; ++i) {
2888 if (!EltC1 || !EltC2)
2907 Type *Ty =
A->getType();
2923 if (
A->getType()->isIntOrIntVectorTy()) {
2925 if (NumSignBits ==
A->getType()->getScalarSizeInBits() &&
2948 Cond->getType()->isIntOrIntVectorTy(1)) {
2974 Cond->getType()->isIntOrIntVectorTy(1) &&
2988 Value *
D,
bool InvertFalseVal) {
2991 Type *OrigType =
A->getType();
2994 if (
Value *
Cond = getSelectCondition(
A,
B, InvertFalseVal)) {
2999 Type *SelTy =
A->getType();
3000 if (
auto *VecTy = dyn_cast<VectorType>(
Cond->getType())) {
3002 unsigned Elts = VecTy->getElementCount().getKnownMinValue();
3023 bool IsAnd,
bool IsLogical,
3030 IsAnd ?
LHS->getInversePredicate() :
LHS->getPredicate();
3032 IsAnd ?
RHS->getInversePredicate() :
RHS->getPredicate();
3041 auto MatchRHSOp = [LHS0, CInt](
const Value *RHSOp) {
3044 (CInt->
isZero() && RHSOp == LHS0);
3075 if (
Value *V = foldAndOrOfICmpsOfAndWithPow2(LHS, RHS, &
I, IsAnd, IsLogical))
3079 Value *LHS0 =
LHS->getOperand(0), *RHS0 =
RHS->getOperand(0);
3080 Value *LHS1 =
LHS->getOperand(1), *RHS1 =
RHS->getOperand(1);
3081 const APInt *LHSC =
nullptr, *RHSC =
nullptr;
3088 if (LHS0 == RHS1 && LHS1 == RHS0) {
3092 if (LHS0 == RHS0 && LHS1 == RHS1) {
3095 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
3144 if (IsAnd && !IsLogical)
3162 if (
Value *
X = foldEqOfParts(LHS, RHS, IsAnd))
3197 const APInt *AndC, *SmallC =
nullptr, *BigC =
nullptr;
3211 if (SmallC && BigC) {
3231 bool TrueIfSignedL, TrueIfSignedR;
3237 if ((TrueIfSignedL && !TrueIfSignedR &&
3240 (!TrueIfSignedL && TrueIfSignedR &&
3247 if ((TrueIfSignedL && !TrueIfSignedR &&
3250 (!TrueIfSignedL && TrueIfSignedR &&
3259 return foldAndOrOfICmpsUsingRanges(LHS, RHS, IsAnd);
3298 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
3299 Type *Ty =
I.getType();
3301 if (
auto *SI0 = dyn_cast<SelectInst>(Op0)) {
3303 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
false))
3306 if (
auto *SI1 = dyn_cast<SelectInst>(Op1)) {
3308 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
false))
3345 return BinaryOperator::CreateMul(
X, IncrementY);
3350 return BinaryOperator::CreateOr(
X,
Y);
3358 const APInt *C0, *C1;
3377 if ((*C0 & *C1).
isZero()) {
3383 return BinaryOperator::CreateAnd(
A, C01);
3390 return BinaryOperator::CreateAnd(
B, C01);
3394 const APInt *C2, *C3;
3400 return BinaryOperator::CreateAnd(
Or, C01);
3410 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D))
3412 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B))
3414 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D))
3416 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B))
3418 if (
Value *V = matchSelectFromAndOr(
B,
D,
A,
C))
3420 if (
Value *V = matchSelectFromAndOr(
B,
D,
C,
A))
3422 if (
Value *V = matchSelectFromAndOr(
D,
B,
A,
C))
3424 if (
Value *V = matchSelectFromAndOr(
D,
B,
C,
A))
3433 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D,
true))
3435 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B,
true))
3437 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D,
true))
3439 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B,
true))
3446 return BinaryOperator::CreateOr(Op0,
C);
3451 return BinaryOperator::CreateOr(Op1,
C);
3455 return BinaryOperator::CreateOr(
C, Op1);
3459 return BinaryOperator::CreateOr(Op0,
C);
3469 bool SwappedForXor =
false;
3472 SwappedForXor =
true;
3479 return BinaryOperator::CreateOr(Op0,
B);
3481 return BinaryOperator::CreateOr(Op0,
A);
3487 return BinaryOperator::CreateOr(
A,
B);
3515 return BinaryOperator::CreateOr(Nand,
C);
3522 return BinaryOperator::CreateOr(NotB, Op0);
3526 return BinaryOperator::CreateOr(NotA, Op0);
3534 if ((Op0 ==
B->getOperand(0) || Op0 ==
B->getOperand(1)) &&
3535 Op1->
hasOneUse() && (
B->getOpcode() == Instruction::Or ||
3536 B->getOpcode() == Instruction::Xor)) {
3537 Value *NotOp = Op0 ==
B->getOperand(0) ?
B->getOperand(1) :
3540 return BinaryOperator::CreateOr(Not, Op0);
3557 bool IsLogical = isa<SelectInst>(Op1);
3559 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
3561 foldAndOrOfICmps(
LHS, Cmp,
I,
false, IsLogical))
3566 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
3567 if (
Value *Res = foldAndOrOfICmps(
LHS, Cmp,
I,
false,
3574 bool IsLogical = isa<SelectInst>(Op0);
3576 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
3578 foldAndOrOfICmps(Cmp,
RHS,
I,
false, IsLogical))
3583 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
3584 if (
Value *Res = foldAndOrOfICmps(Cmp,
RHS,
I,
false,
3592 if (
FCmpInst *
LHS = dyn_cast<FCmpInst>(
I.getOperand(0)))
3593 if (
FCmpInst *
RHS = dyn_cast<FCmpInst>(
I.getOperand(1)))
3594 if (
Value *Res = foldLogicOfFCmps(
LHS,
RHS,
false))
3612 A->getType()->isIntOrIntVectorTy(1))
3625 return BinaryOperator::CreateOr(Inner, CI);
3632 Value *
X =
nullptr, *
Y =
nullptr;
3664 return BinaryOperator::CreateXor(
A,
B);
3680 Value *
Mul, *Ov, *MulIsNotZero, *UMulWithOv;
3697 if (
match(UMulWithOv, m_Intrinsic<Intrinsic::umul_with_overflow>(
3701 return BinaryOperator::CreateAnd(NotNullA, NotNullB);
3721 Value *Start =
nullptr, *Step =
nullptr;
3739 return BinaryOperator::CreateOr(
3751 return BinaryOperator::CreateOr(
3759 return Canonicalized;
3761 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
3781 Attribute::NoImplicitFloat)) {