23using namespace PatternMatch;
25#define DEBUG_TYPE "instcombine"
56 "Lo is not < Hi in range emission code!");
58 Type *Ty = V->getType();
63 if (
isSigned ?
Lo.isMinSignedValue() :
Lo.isMinValue()) {
120 const APInt *ConstA =
nullptr, *ConstB =
nullptr, *ConstC =
nullptr;
125 bool IsAPow2 = ConstA && ConstA->
isPowerOf2();
126 bool IsBPow2 = ConstB && ConstB->isPowerOf2();
127 unsigned MaskVal = 0;
128 if (ConstC && ConstC->isZero()) {
147 }
else if (ConstA && ConstC && ConstC->
isSubsetOf(*ConstA)) {
157 }
else if (ConstB && ConstC && ConstC->isSubsetOf(*ConstB)) {
185 LHS,
RHS, Pred,
true,
true);
191 Y = ConstantInt::get(
X->getType(), Res->Mask);
192 Z = ConstantInt::get(
X->getType(), Res->C);
217 Value *L11, *L12, *L21, *L22;
220 L21 = L22 = L1 =
nullptr;
245 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
248 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
265 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
270 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
293 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
298 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
307 assert(Ok &&
"Failed to find AND on the right side of the RHS icmp.");
313 }
else if (L12 ==
A) {
316 }
else if (L21 ==
A) {
319 }
else if (L22 ==
A) {
326 return std::optional<std::pair<unsigned, unsigned>>(
327 std::make_pair(LeftType, RightType));
349 const APInt *BCst, *DCst, *OrigECst;
360 APInt ECst = *OrigECst;
366 if (*BCst == 0 || *DCst == 0)
377 Attribute::StrictFP)) {
378 Type *Ty = Src->getType()->getScalarType();
385 APInt FractionBits = ~ExpBits;
387 if (*BCst != FractionBits)
412 if ((((*BCst & *DCst) & ECst) == 0) &&
413 (*BCst & (*BCst ^ *DCst)).isPowerOf2()) {
414 APInt BorD = *BCst | *DCst;
415 APInt BandBxorDorE = (*BCst & (*BCst ^ *DCst)) | ECst;
416 Value *NewMask = ConstantInt::get(
A->getType(), BorD);
417 Value *NewMaskedValue = ConstantInt::get(
A->getType(), BandBxorDorE);
419 return Builder.
CreateICmp(NewCC, NewAnd, NewMaskedValue);
422 auto IsSubSetOrEqual = [](
const APInt *C1,
const APInt *C2) {
423 return (*C1 & *C2) == *C1;
425 auto IsSuperSetOrEqual = [](
const APInt *C1,
const APInt *C2) {
426 return (*C1 & *C2) == *C2;
435 if (!IsSubSetOrEqual(BCst, DCst) && !IsSuperSetOrEqual(BCst, DCst))
447 if (IsSubSetOrEqual(BCst, DCst))
448 return ConstantInt::get(
LHS->
getType(), !IsAnd);
458 if (IsSuperSetOrEqual(BCst, DCst)) {
460 RHS->setSameSign(
false);
466 assert(IsSubSetOrEqual(BCst, DCst) &&
"Precondition due to above code");
467 if ((*BCst & ECst) != 0) {
469 RHS->setSameSign(
false);
476 return ConstantInt::get(
LHS->
getType(), !IsAnd);
488 "Expected equality predicates for masked type of icmps.");
500 LHS,
RHS, IsAnd,
A,
B,
D, E, PredL, PredR, Builder)) {
505 RHS,
LHS, IsAnd,
A,
D,
B,
C, PredR, PredL, Builder)) {
517 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *E =
nullptr;
519 std::optional<std::pair<unsigned, unsigned>> MaskPair =
524 "Expected equality predicates for masked type of icmps.");
525 unsigned LHSMask = MaskPair->first;
526 unsigned RHSMask = MaskPair->second;
527 unsigned Mask = LHSMask & RHSMask;
532 LHS,
RHS, IsAnd,
A,
B,
C,
D, E, PredL, PredR, LHSMask, RHSMask,
568 return Builder.
CreateICmp(NewCC, NewAnd, Zero);
577 return Builder.
CreateICmp(NewCC, NewAnd, NewOr);
592 const APInt *ConstB, *ConstD;
602 APInt NewMask = *ConstB & *ConstD;
603 if (NewMask == *ConstB)
605 else if (NewMask == *ConstD)
614 APInt NewMask = *ConstB | *ConstD;
615 if (NewMask == *ConstB)
617 else if (NewMask == *ConstD)
644 const APInt *OldConstC, *OldConstE;
650 const APInt ConstC = PredL !=
CC ? *ConstB ^ *OldConstC : *OldConstC;
651 const APInt ConstE = PredR !=
CC ? *ConstD ^ *OldConstE : *OldConstE;
653 if (((*ConstB & *ConstD) & (ConstC ^ ConstE)).getBoolValue())
654 return IsNot ? nullptr : ConstantInt::get(
LHS->
getType(), !IsAnd);
656 if (IsNot && !ConstB->
isSubsetOf(*ConstD) && !ConstD->isSubsetOf(*ConstB))
661 BD = *ConstB & *ConstD;
662 CE = ConstC & ConstE;
664 BD = *ConstB | *ConstD;
665 CE = ConstC | ConstE;
668 Value *CEVal = ConstantInt::get(
A->getType(), CE);
673 return FoldBMixed(NewCC,
false);
675 return FoldBMixed(NewCC,
true);
725 default:
return nullptr;
749 if (
LHS->getPredicate() != Pred ||
RHS->getPredicate() != Pred)
780Value *InstCombinerImpl::foldAndOrOfICmpsOfAndWithPow2(
ICmpInst *LHS,
786 if (
LHS->getPredicate() != Pred ||
RHS->getPredicate() != Pred)
796 if (L1 ==
R2 || L2 ==
R2)
854 auto tryToMatchSignedTruncationCheck = [](
ICmpInst *ICmp,
Value *&
X,
855 APInt &SignBitMask) ->
bool {
856 const APInt *I01, *I1;
860 I1->ugt(*I01) && I01->
shl(1) == *I1))
872 if (tryToMatchSignedTruncationCheck(ICmp1, X1, HighestBit))
874 else if (tryToMatchSignedTruncationCheck(ICmp0, X1, HighestBit))
879 assert(HighestBit.
isPowerOf2() &&
"expected to be power of two (non-zero)");
883 APInt &UnsetBitsMask) ->
bool {
891 UnsetBitsMask = Res->Mask;
899 UnsetBitsMask = *Mask;
908 if (!tryToDecompose(OtherICmp, X0, UnsetBitsMask))
911 assert(!UnsetBitsMask.
isZero() &&
"empty mask makes no sense.");
926 APInt SignBitsMask = ~(HighestBit - 1U);
933 if (!UnsetBitsMask.
isSubsetOf(SignBitsMask)) {
934 APInt OtherHighestBit = (~UnsetBitsMask) + 1U;
942 return Builder.
CreateICmpULT(
X, ConstantInt::get(
X->getType(), HighestBit),
943 CxtI.
getName() +
".simplified");
960 auto *CtPop = cast<Instruction>(Cmp0->
getOperand(0));
963 CtPop->dropPoisonGeneratingAnnotations();
965 return Builder.
CreateICmpUGT(CtPop, ConstantInt::get(CtPop->getType(), 1));
969 CtPop->dropPoisonGeneratingAnnotations();
971 return Builder.
CreateICmpULT(CtPop, ConstantInt::get(CtPop->getType(), 2));
996 auto *CtPop = cast<Instruction>(Cmp1->
getOperand(0));
998 CtPop->dropPoisonGeneratingAnnotations();
1000 return Builder.
CreateICmpEQ(CtPop, ConstantInt::get(CtPop->getType(), 1));
1008 auto *CtPop = cast<Instruction>(Cmp1->
getOperand(0));
1010 CtPop->dropPoisonGeneratingAnnotations();
1012 return Builder.
CreateICmpNE(CtPop, ConstantInt::get(CtPop->getType(), 1));
1026 "Expected equality predicates for masked type of icmps.");
1046 const APInt *BCst, *DCst, *ECst;
1049 (isa<PoisonValue>(
B) ||
1054 if (
const auto *BVTy = dyn_cast<VectorType>(
B->getType())) {
1055 const auto *BFVTy = dyn_cast<FixedVectorType>(BVTy);
1056 const auto *BConst = dyn_cast<Constant>(
B);
1057 const auto *DConst = dyn_cast<Constant>(
D);
1058 const auto *EConst = dyn_cast<Constant>(E);
1060 if (!BFVTy || !BConst || !DConst || !EConst)
1063 for (
unsigned I = 0;
I != BFVTy->getNumElements(); ++
I) {
1064 const auto *BElt = BConst->getAggregateElement(
I);
1065 const auto *DElt = DConst->getAggregateElement(
I);
1066 const auto *EElt = EConst->getAggregateElement(
I);
1068 if (!BElt || !DElt || !EElt)
1070 if (!isReducible(BElt, DElt, EElt))
1075 if (!isReducible(
B,
D, E))
1093 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *E =
nullptr;
1099 std::optional<std::pair<unsigned, unsigned>> MaskPair =
1105 unsigned CmpMask0 = MaskPair->first;
1106 unsigned CmpMask1 = MaskPair->second;
1107 if ((CmpMask0 &
Mask_AllZeros) && (CmpMask1 == compareBMask)) {
1111 }
else if ((CmpMask0 == compareBMask) && (CmpMask1 &
Mask_AllZeros)) {
1122 ICmpInst *UnsignedICmp,
bool IsAnd,
1134 if (
match(UnsignedICmp,
1150 IsAnd && GetKnownNonZeroAndOther(
B,
A))
1153 !IsAnd && GetKnownNonZeroAndOther(
B,
A))
1170 return std::nullopt;
1172 unsigned NumOriginalBits =
X->getType()->getScalarSizeInBits();
1173 unsigned NumExtractedBits = V->getType()->getScalarSizeInBits();
1179 Shift->
ule(NumOriginalBits - NumExtractedBits))
1181 return {{
X, 0, NumExtractedBits}};
1189 Type *TruncTy = V->getType()->getWithNewBitWidth(
P.NumBits);
1190 if (TruncTy != V->getType())
1198Value *InstCombinerImpl::foldEqOfParts(
Value *Cmp0,
Value *Cmp1,
bool IsAnd) {
1203 auto GetMatchPart = [&](
Value *CmpV,
1204 unsigned OpNo) -> std::optional<IntPart> {
1213 return {{OpNo == 0 ?
X :
Y, 0, 1}};
1215 auto *
Cmp = dyn_cast<ICmpInst>(CmpV);
1217 return std::nullopt;
1219 if (Pred ==
Cmp->getPredicate())
1228 return std::nullopt;
1237 return std::nullopt;
1239 return std::nullopt;
1244 return {{
I->getOperand(OpNo),
From,
C->getBitWidth() -
From}};
1247 std::optional<IntPart> L0 = GetMatchPart(Cmp0, 0);
1248 std::optional<IntPart> R0 = GetMatchPart(Cmp0, 1);
1249 std::optional<IntPart> L1 = GetMatchPart(Cmp1, 0);
1250 std::optional<IntPart> R1 = GetMatchPart(Cmp1, 1);
1251 if (!L0 || !R0 || !L1 || !R1)
1256 if (L0->From != L1->From || R0->From != R1->From) {
1257 if (L0->From != R1->From || R0->From != L1->From)
1264 if (L0->StartBit + L0->NumBits != L1->StartBit ||
1265 R0->StartBit + R0->NumBits != R1->StartBit) {
1266 if (L1->StartBit + L1->NumBits != L0->StartBit ||
1267 R1->StartBit + R1->NumBits != R0->StartBit)
1274 IntPart L = {L0->From, L0->StartBit, L0->NumBits + L1->NumBits};
1275 IntPart R = {R0->From, R0->StartBit, R0->NumBits + R1->NumBits};
1285 bool IsAnd,
bool IsLogical,
1314 if (!SubstituteCmp) {
1324 return Builder.
CreateBinOp(IsAnd ? Instruction::And : Instruction::Or, Cmp0,
1332Value *InstCombinerImpl::foldAndOrOfICmpsUsingRanges(
ICmpInst *ICmp1,
1337 const APInt *C1, *C2;
1344 const APInt *Offset1 =
nullptr, *Offset2 =
nullptr;
1379 if (!LowerDiff.
isPowerOf2() || LowerDiff != UpperDiff ||
1392 CR->getEquivalentICmp(NewPred, NewC,
Offset);
1424 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1425 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1434 FMF &=
RHS->getFastMathFlags();
1441 bool IsAnd,
bool IsLogicalSelect) {
1442 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1443 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1446 if (LHS0 == RHS1 && RHS0 == LHS1) {
1466 if (LHS0 == RHS0 && LHS1 == RHS1) {
1469 unsigned NewPred = IsAnd ? FCmpCodeL & FCmpCodeR : FCmpCodeL | FCmpCodeR;
1475 FMF &=
RHS->getFastMathFlags();
1482 if (!IsLogicalSelect &&
1497 RHS->getFastMathFlags());
1517 auto [ClassValRHS, ClassMaskRHS] =
1520 auto [ClassValLHS, ClassMaskLHS] =
1522 if (ClassValLHS == ClassValRHS) {
1523 unsigned CombinedMask = IsAnd ? (ClassMaskLHS & ClassMaskRHS)
1524 : (ClassMaskLHS | ClassMaskRHS);
1526 Intrinsic::is_fpclass, {ClassValLHS->getType()},
1555 if (IsLessThanOrLessEqual(IsAnd ? PredR : PredL)) {
1559 if (IsLessThanOrLessEqual(IsAnd ? PredL : PredR)) {
1562 if (!IsLogicalSelect)
1563 NewFlag |=
RHS->getFastMathFlags();
1568 ConstantFP::get(LHS0->
getType(), *LHSC));
1579 auto *FCmp = dyn_cast<FCmpInst>(
Op);
1580 if (!FCmp || !FCmp->hasOneUse())
1583 std::tie(ClassVal, ClassMask) =
1584 fcmpToClassTest(FCmp->getPredicate(), *FCmp->getParent()->getParent(),
1585 FCmp->getOperand(0), FCmp->getOperand(1));
1586 return ClassVal !=
nullptr;
1597 Value *ClassVal0 =
nullptr;
1598 Value *ClassVal1 =
nullptr;
1615 ClassVal0 == ClassVal1) {
1616 unsigned NewClassMask;
1618 case Instruction::And:
1619 NewClassMask = ClassMask0 & ClassMask1;
1621 case Instruction::Or:
1622 NewClassMask = ClassMask0 | ClassMask1;
1624 case Instruction::Xor:
1625 NewClassMask = ClassMask0 ^ ClassMask1;
1632 auto *
II = cast<IntrinsicInst>(Op0);
1634 1, ConstantInt::get(
II->getArgOperand(1)->getType(), NewClassMask));
1639 auto *
II = cast<IntrinsicInst>(Op1);
1641 1, ConstantInt::get(
II->getArgOperand(1)->getType(), NewClassMask));
1661Instruction *InstCombinerImpl::canonicalizeConditionalNegationViaMathToSelect(
1663 assert(
I.getOpcode() == BinaryOperator::Xor &&
"Only for xor!");
1668 !
Cond->getType()->isIntOrIntVectorTy(1) ||
1682 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1683 "Expecting and/or op for fcmp transform");
1702 X->getType() !=
Y->getType())
1706 X->getType() !=
Y->getType())
1712 if (
auto *NewFCmpInst = dyn_cast<FCmpInst>(NewFCmp)) {
1714 NewFCmpInst->copyIRFlags(Op0);
1715 NewFCmpInst->andIRFlags(BO10);
1726 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1727 "Trying to match De Morgan's Laws with something other than and/or");
1731 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1733 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1759bool InstCombinerImpl::shouldOptimizeCast(
CastInst *CI) {
1768 if (
const auto *PrecedingCI = dyn_cast<CastInst>(CastSrc))
1769 if (isEliminableCastPair(PrecedingCI, CI))
1795 return new ZExtInst(NewOp, DestTy);
1803 return new SExtInst(NewOp, DestTy);
1812 auto LogicOpc =
I.getOpcode();
1813 assert(
I.isBitwiseLogicOp() &&
"Unexpected opcode for bitwise logic folding");
1815 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1821 auto FoldBitwiseICmpZeroWithICmp = [&](
Value *Op0,
1836 auto *ICmpR = cast<ZExtInst>(Op1)->getOperand(0);
1842 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op0, Op1))
1845 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op1, Op0))
1848 CastInst *Cast0 = dyn_cast<CastInst>(Op0);
1854 Type *DestTy =
I.getType();
1862 CastInst *Cast1 = dyn_cast<CastInst>(Op1);
1879 unsigned XNumBits =
X->getType()->getScalarSizeInBits();
1880 unsigned YNumBits =
Y->getType()->getScalarSizeInBits();
1881 if (XNumBits < YNumBits)
1899 shouldOptimizeCast(Cast0) && shouldOptimizeCast(Cast1)) {
1910 assert(
I.getOpcode() == Instruction::And);
1911 Value *Op0 =
I.getOperand(0);
1912 Value *Op1 =
I.getOperand(1);
1920 return BinaryOperator::CreateXor(
A,
B);
1936 assert(
I.getOpcode() == Instruction::Or);
1937 Value *Op0 =
I.getOperand(0);
1938 Value *Op1 =
I.getOperand(1);
1963 return BinaryOperator::CreateXor(
A,
B);
1983 Value *Op0 =
And.getOperand(0), *Op1 =
And.getOperand(1);
1997 if (!isa<VectorType>(Ty) && !shouldChangeType(Ty,
X->getType()))
2004 if (Opc == Instruction::LShr || Opc == Instruction::Shl)
2021 assert(Opcode == Instruction::And || Opcode == Instruction::Or);
2025 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
2027 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2034 const auto matchNotOrAnd =
2035 [Opcode, FlippedOpcode](
Value *
Op,
auto m_A,
auto m_B,
auto m_C,
2036 Value *&
X,
bool CountUses =
false) ->
bool {
2037 if (CountUses && !
Op->hasOneUse())
2044 return !CountUses ||
X->hasOneUse();
2060 return (Opcode == Instruction::Or)
2070 return (Opcode == Instruction::Or)
2093 if (Opcode == Instruction::Or && Op0->
hasOneUse() &&
2100 Value *
Or = cast<BinaryOperator>(
X)->getOperand(0);
2132 return (Opcode == Instruction::Or)
2134 : BinaryOperator::CreateOr(
Xor,
X);
2168 if (!isa<Constant>(
X) && !isa<Constant>(
Y) && !isa<Constant>(Z)) {
2170 if (!
X->hasOneUse()) {
2175 if (!
Y->hasOneUse()) {
2196 Type *Ty =
I.getType();
2198 Value *Op0 =
I.getOperand(0);
2199 Value *Op1 =
I.getOperand(1);
2211 case Instruction::And:
2212 if (
C->countl_one() < LastOneMath)
2215 case Instruction::Xor:
2216 case Instruction::Or:
2217 if (
C->countl_zero() < LastOneMath)
2226 ConstantInt::get(Ty, *C2), Op0);
2233 assert((
I.isBitwiseLogicOp() ||
I.getOpcode() == Instruction::Add) &&
2234 "Unexpected opcode");
2237 Constant *ShiftedC1, *ShiftedC2, *AddC;
2238 Type *Ty =
I.getType();
2252 auto *Op0Inst = dyn_cast<Instruction>(
I.getOperand(0));
2253 auto *Op1Inst = dyn_cast<Instruction>(
I.getOperand(1));
2254 if (!Op0Inst || !Op1Inst)
2260 if (ShiftOp != Op1Inst->getOpcode())
2264 if (
I.getOpcode() == Instruction::Add && ShiftOp != Instruction::Shl)
2284 assert(
I.isBitwiseLogicOp() &&
"Should and/or/xor");
2285 if (!
I.getOperand(0)->hasOneUse())
2292 if (
Y && (!
Y->hasOneUse() ||
X->getIntrinsicID() !=
Y->getIntrinsicID()))
2298 if (!
Y && (!(IID == Intrinsic::bswap || IID == Intrinsic::bitreverse) ||
2303 case Intrinsic::fshl:
2304 case Intrinsic::fshr: {
2305 if (
X->getOperand(2) !=
Y->getOperand(2))
2308 Builder.
CreateBinOp(
I.getOpcode(),
X->getOperand(0),
Y->getOperand(0));
2310 Builder.
CreateBinOp(
I.getOpcode(),
X->getOperand(1),
Y->getOperand(1));
2315 case Intrinsic::bswap:
2316 case Intrinsic::bitreverse: {
2318 I.getOpcode(),
X->getOperand(0),
2319 Y ?
Y->getOperand(0)
2320 : ConstantInt::get(
I.getType(), IID == Intrinsic::bswap
2340 unsigned Depth = 0) {
2347 auto *
I = dyn_cast<BinaryOperator>(V);
2348 if (!
I || !
I->isBitwiseLogicOp() ||
Depth >= 3)
2351 if (!
I->hasOneUse())
2352 SimplifyOnly =
true;
2355 SimplifyOnly, IC,
Depth + 1);
2357 SimplifyOnly, IC,
Depth + 1);
2358 if (!NewOp0 && !NewOp1)
2362 NewOp0 =
I->getOperand(0);
2364 NewOp1 =
I->getOperand(1);
2379 Type *Ty =
I.getType();
2413 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2448 Constant *NewC = ConstantInt::get(Ty, *
C & *XorC);
2451 return BinaryOperator::CreateXor(
And, NewC);
2462 APInt Together = *
C & *OrC;
2465 return BinaryOperator::CreateOr(
And, ConstantInt::get(Ty, Together));
2469 const APInt *ShiftC;
2471 ShiftC->
ult(Width)) {
2476 Constant *ShAmtC = ConstantInt::get(Ty, ShiftC->
zext(Width));
2477 return BinaryOperator::CreateLShr(Sext, ShAmtC);
2485 return BinaryOperator::CreateLShr(
X, ConstantInt::get(Ty, *ShiftC));
2493 if (Op0->
hasOneUse() &&
C->isPowerOf2() && (*AddC & (*
C - 1)) == 0) {
2494 assert((*
C & *AddC) != 0 &&
"Expected common bit");
2496 return BinaryOperator::CreateXor(NewAnd, Op1);
2503 switch (
B->getOpcode()) {
2504 case Instruction::Xor:
2505 case Instruction::Or:
2506 case Instruction::Mul:
2507 case Instruction::Add:
2508 case Instruction::Sub:
2524 C->isIntN(
X->getType()->getScalarSizeInBits())) {
2525 unsigned XWidth =
X->getType()->getScalarSizeInBits();
2526 Constant *TruncC1 = ConstantInt::get(
X->getType(), C1->
trunc(XWidth));
2530 Constant *TruncC = ConstantInt::get(
X->getType(),
C->trunc(XWidth));
2540 C->isMask(
X->getType()->getScalarSizeInBits())) {
2550 C->isMask(
X->getType()->getScalarSizeInBits())) {
2584 if (
C->isPowerOf2() &&
2587 int Log2C =
C->exactLogBase2();
2589 cast<BinaryOperator>(Op0)->getOpcode() == Instruction::Shl;
2590 int BitNum = IsShiftLeft ? Log2C - Log2ShiftC : Log2ShiftC - Log2C;
2591 assert(BitNum >= 0 &&
"Expected demanded bits to handle impossible mask");
2624 if (Cmp && Cmp->isZeroValue()) {
2649 Attribute::NoImplicitFloat)) {
2665 X->getType()->getScalarSizeInBits())))) {
2667 return BinaryOperator::CreateAnd(SExt, Op1);
2673 if (
I.getType()->isIntOrIntVectorTy(1)) {
2674 if (
auto *SI0 = dyn_cast<SelectInst>(Op0)) {
2676 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
true))
2679 if (
auto *SI1 = dyn_cast<SelectInst>(Op1)) {
2681 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
true))
2696 return BinaryOperator::CreateAnd(Op0,
B);
2699 return BinaryOperator::CreateAnd(Op1,
B);
2707 if (NotC !=
nullptr)
2708 return BinaryOperator::CreateAnd(Op0, NotC);
2717 if (NotC !=
nullptr)
2727 return BinaryOperator::CreateAnd(
A,
B);
2735 return BinaryOperator::CreateAnd(
A,
B);
2755 foldBooleanAndOr(Op0, Op1,
I,
true,
false))
2761 bool IsLogical = isa<SelectInst>(Op1);
2763 if (
Value *Res = foldBooleanAndOr(Op0,
X,
I,
true, IsLogical))
2767 if (
Value *Res = foldBooleanAndOr(Op0,
Y,
I,
true,
2773 bool IsLogical = isa<SelectInst>(Op0);
2775 if (
Value *Res = foldBooleanAndOr(
X, Op1,
I,
true, IsLogical))
2779 if (
Value *Res = foldBooleanAndOr(
Y, Op1,
I,
true,
2788 if (
Instruction *CastedAnd = foldCastedBitwiseLogic(
I))
2801 A->getType()->isIntOrIntVectorTy(1))
2807 A->getType()->isIntOrIntVectorTy(1))
2812 A->getType()->isIntOrIntVectorTy(1))
2819 if (
A->getType()->isIntOrIntVectorTy(1))
2832 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2841 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2852 Value *Start =
nullptr, *Step =
nullptr;
2860 return Canonicalized;
2862 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
2874 return BinaryOperator::CreateAnd(V, Op1);
2878 return BinaryOperator::CreateAnd(Op0, V);
2885 bool MatchBitReversals) {
2893 for (
auto *Inst : Insts) {
2894 Inst->setDebugLoc(
I.getDebugLoc());
2900std::optional<std::pair<Intrinsic::ID, SmallVector<Value *, 3>>>
2904 assert(
Or.getOpcode() == BinaryOperator::Or &&
"Expecting or instruction");
2906 unsigned Width =
Or.getType()->getScalarSizeInBits();
2911 return std::nullopt;
2918 if (isa<BinaryOperator>(Or0) && isa<BinaryOperator>(Or1)) {
2919 Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
2925 return std::nullopt;
2928 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2934 Or1->
getOpcode() == BinaryOperator::LShr &&
2935 "Illegal or(shift,shift) pair");
2939 auto matchShiftAmount = [&](
Value *L,
Value *R,
unsigned Width) ->
Value * {
2941 const APInt *LI, *RI;
2943 if (LI->
ult(Width) && RI->
ult(Width) && (*LI + *RI) == Width)
2944 return ConstantInt::get(L->getType(), *LI);
2968 if (ShVal0 != ShVal1)
2979 unsigned Mask = Width - 1;
3003 Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, Width);
3005 ShAmt = matchShiftAmount(ShAmt1, ShAmt0, Width);
3009 return std::nullopt;
3011 FShiftArgs = {ShVal0, ShVal1, ShAmt};
3012 }
else if (isa<ZExtInst>(Or0) || isa<ZExtInst>(Or1)) {
3024 if (!isa<ZExtInst>(Or1))
3028 const APInt *ZextHighShlAmt;
3031 return std::nullopt;
3035 return std::nullopt;
3037 unsigned HighSize =
High->getType()->getScalarSizeInBits();
3038 unsigned LowSize =
Low->getType()->getScalarSizeInBits();
3041 if (ZextHighShlAmt->
ult(LowSize) || ZextHighShlAmt->
ugt(Width - HighSize))
3042 return std::nullopt;
3049 if (!isa<ZExtInst>(
Y))
3052 const APInt *ZextLowShlAmt;
3059 if (*ZextLowShlAmt + *ZextHighShlAmt != Width)
3065 ZextLowShlAmt->
ule(Width - LowSize) &&
"Invalid concat");
3067 FShiftArgs = {U, U, ConstantInt::get(Or0->
getType(), *ZextHighShlAmt)};
3072 if (FShiftArgs.
empty())
3073 return std::nullopt;
3075 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
3076 return std::make_pair(IID, FShiftArgs);
3082 auto [IID, FShiftArgs] = *Opt;
3094 assert(
Or.getOpcode() == Instruction::Or &&
"bswap requires an 'or'");
3095 Value *Op0 =
Or.getOperand(0), *Op1 =
Or.getOperand(1);
3099 if ((Width & 1) != 0)
3101 unsigned HalfWidth = Width / 2;
3104 if (!isa<ZExtInst>(Op0))
3108 Value *LowerSrc, *ShlVal, *UpperSrc;
3121 NewUpper = Builder.
CreateShl(NewUpper, HalfWidth);
3128 Value *LowerBSwap, *UpperBSwap;
3131 return ConcatIntrinsicCalls(Intrinsic::bswap, UpperBSwap, LowerBSwap);
3135 Value *LowerBRev, *UpperBRev;
3138 return ConcatIntrinsicCalls(Intrinsic::bitreverse, UpperBRev, LowerBRev);
3145 unsigned NumElts = cast<FixedVectorType>(C1->
getType())->getNumElements();
3146 for (
unsigned i = 0; i != NumElts; ++i) {
3149 if (!EltC1 || !EltC2)
3168 Type *Ty =
A->getType();
3184 if (
A->getType()->isIntOrIntVectorTy()) {
3186 if (NumSignBits ==
A->getType()->getScalarSizeInBits() &&
3209 Cond->getType()->isIntOrIntVectorTy(1)) {
3235 Cond->getType()->isIntOrIntVectorTy(1) &&
3249 Value *
D,
bool InvertFalseVal) {
3252 Type *OrigType =
A->getType();
3255 if (
Value *
Cond = getSelectCondition(
A,
C, InvertFalseVal)) {
3260 Type *SelTy =
A->getType();
3261 if (
auto *VecTy = dyn_cast<VectorType>(
Cond->getType())) {
3263 unsigned Elts = VecTy->getElementCount().getKnownMinValue();
3284 bool IsAnd,
bool IsLogical,
3291 IsAnd ?
LHS->getInversePredicate() :
LHS->getPredicate();
3293 IsAnd ?
RHS->getInversePredicate() :
RHS->getPredicate();
3302 auto MatchRHSOp = [LHS0, CInt](
const Value *RHSOp) {
3305 (CInt->
isZero() && RHSOp == LHS0);
3336 if (
Value *V = foldAndOrOfICmpsOfAndWithPow2(LHS, RHS, &
I, IsAnd, IsLogical))
3340 Value *LHS0 =
LHS->getOperand(0), *RHS0 =
RHS->getOperand(0);
3341 Value *LHS1 =
LHS->getOperand(1), *RHS1 =
RHS->getOperand(1);
3343 const APInt *LHSC =
nullptr, *RHSC =
nullptr;
3350 if (LHS0 == RHS1 && LHS1 == RHS0) {
3354 if (LHS0 == RHS0 && LHS1 == RHS1) {
3357 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
3386 RHS->setSameSign(
false);
3412 if (IsAnd && !IsLogical)
3469 const APInt *AndC, *SmallC =
nullptr, *BigC =
nullptr;
3483 if (SmallC && BigC) {
3484 unsigned BigBitSize = BigC->getBitWidth();
3503 bool TrueIfSignedL, TrueIfSignedR;
3509 if ((TrueIfSignedL && !TrueIfSignedR &&
3512 (!TrueIfSignedL && TrueIfSignedR &&
3519 if ((TrueIfSignedL && !TrueIfSignedR &&
3522 (!TrueIfSignedL && TrueIfSignedR &&
3531 return foldAndOrOfICmpsUsingRanges(LHS, RHS, IsAnd);
3542 if (
auto *LHSCmp = dyn_cast<ICmpInst>(LHS))
3543 if (
auto *RHSCmp = dyn_cast<ICmpInst>(RHS))
3544 if (
Value *Res = foldAndOrOfICmps(LHSCmp, RHSCmp,
I, IsAnd, IsLogical))
3547 if (
auto *LHSCmp = dyn_cast<FCmpInst>(LHS))
3548 if (
auto *RHSCmp = dyn_cast<FCmpInst>(RHS))
3549 if (
Value *Res = foldLogicOfFCmps(LHSCmp, RHSCmp, IsAnd, IsLogical))
3552 if (
Value *Res = foldEqOfParts(LHS, RHS, IsAnd))
3560 assert(
I.getOpcode() == Instruction::Or &&
3561 "Simplification only supports or at the moment.");
3563 Value *Cmp1, *Cmp2, *Cmp3, *Cmp4;
3615 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
3616 Type *Ty =
I.getType();
3618 if (
auto *SI0 = dyn_cast<SelectInst>(Op0)) {
3620 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
false))
3623 if (
auto *SI1 = dyn_cast<SelectInst>(Op1)) {
3625 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
false))
3649 if (cast<PossiblyDisjointInst>(
I).isDisjoint()) {
3667 return BinaryOperator::CreateXor(
Or, ConstantInt::get(Ty, *CV));
3675 return BinaryOperator::CreateMul(
X, IncrementY);
3684 const APInt *C0, *C1;
3703 if ((*C0 & *C1).
isZero()) {
3708 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
3709 return BinaryOperator::CreateAnd(
A, C01);
3715 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
3716 return BinaryOperator::CreateAnd(
B, C01);
3720 const APInt *C2, *C3;
3725 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
3726 return BinaryOperator::CreateAnd(
Or, C01);
3736 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D))
3738 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B))
3740 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D))
3742 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B))
3744 if (
Value *V = matchSelectFromAndOr(
B,
D,
A,
C))
3746 if (
Value *V = matchSelectFromAndOr(
B,
D,
C,
A))
3748 if (
Value *V = matchSelectFromAndOr(
D,
B,
A,
C))
3750 if (
Value *V = matchSelectFromAndOr(
D,
B,
C,
A))
3759 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D,
true))
3761 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B,
true))
3763 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D,
true))
3765 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B,
true))
3774 return BinaryOperator::CreateOr(Op0,
C);
3781 return BinaryOperator::CreateOr(Op1,
C);
3787 bool SwappedForXor =
false;
3790 SwappedForXor =
true;
3797 return BinaryOperator::CreateOr(Op0,
B);
3799 return BinaryOperator::CreateOr(Op0,
A);
3804 return BinaryOperator::CreateOr(
A,
B);
3832 return BinaryOperator::CreateOr(Nand,
C);
3840 foldBooleanAndOr(Op0, Op1,
I,
false,
false))
3846 bool IsLogical = isa<SelectInst>(Op1);
3848 if (
Value *Res = foldBooleanAndOr(Op0,
X,
I,
false, IsLogical))
3852 if (
Value *Res = foldBooleanAndOr(Op0,
Y,
I,
false,
3858 bool IsLogical = isa<SelectInst>(Op0);
3860 if (
Value *Res = foldBooleanAndOr(
X, Op1,
I,
false, IsLogical))
3864 if (
Value *Res = foldBooleanAndOr(
Y, Op1,
I,
false,
3885 A->getType()->isIntOrIntVectorTy(1))