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)) {
188 Y = ConstantInt::get(
X->getType(), Mask);
189 Z = ConstantInt::get(
X->getType(), 0);
214 Value *L11, *L12, *L21, *L22;
217 L21 = L22 = L1 =
nullptr;
242 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
245 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
262 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
267 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
286 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
291 }
else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
300 assert(Ok &&
"Failed to find AND on the right side of the RHS icmp.");
306 }
else if (L12 ==
A) {
309 }
else if (L21 ==
A) {
312 }
else if (L22 ==
A) {
319 return std::optional<std::pair<unsigned, unsigned>>(
320 std::make_pair(LeftType, RightType));
342 const APInt *BCst, *DCst, *OrigECst;
353 APInt ECst = *OrigECst;
359 if (*BCst == 0 || *DCst == 0)
370 Attribute::StrictFP)) {
371 Type *Ty = Src->getType()->getScalarType();
378 APInt FractionBits = ~ExpBits;
380 if (*BCst != FractionBits)
405 if ((((*BCst & *DCst) & ECst) == 0) &&
406 (*BCst & (*BCst ^ *DCst)).isPowerOf2()) {
407 APInt BorD = *BCst | *DCst;
408 APInt BandBxorDorE = (*BCst & (*BCst ^ *DCst)) | ECst;
409 Value *NewMask = ConstantInt::get(
A->getType(), BorD);
410 Value *NewMaskedValue = ConstantInt::get(
A->getType(), BandBxorDorE);
412 return Builder.
CreateICmp(NewCC, NewAnd, NewMaskedValue);
415 auto IsSubSetOrEqual = [](
const APInt *C1,
const APInt *C2) {
416 return (*C1 & *C2) == *C1;
418 auto IsSuperSetOrEqual = [](
const APInt *C1,
const APInt *C2) {
419 return (*C1 & *C2) == *C2;
428 if (!IsSubSetOrEqual(BCst, DCst) && !IsSuperSetOrEqual(BCst, DCst))
440 if (IsSubSetOrEqual(BCst, DCst))
441 return ConstantInt::get(
LHS->
getType(), !IsAnd);
451 if (IsSuperSetOrEqual(BCst, DCst))
456 assert(IsSubSetOrEqual(BCst, DCst) &&
"Precondition due to above code");
457 if ((*BCst & ECst) != 0)
463 return ConstantInt::get(
LHS->
getType(), !IsAnd);
475 "Expected equality predicates for masked type of icmps.");
487 LHS,
RHS, IsAnd,
A,
B,
D, E, PredL, PredR, Builder)) {
492 RHS,
LHS, IsAnd,
A,
D,
B,
C, PredR, PredL, Builder)) {
504 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *E =
nullptr;
506 std::optional<std::pair<unsigned, unsigned>> MaskPair =
511 "Expected equality predicates for masked type of icmps.");
512 unsigned LHSMask = MaskPair->first;
513 unsigned RHSMask = MaskPair->second;
514 unsigned Mask = LHSMask & RHSMask;
519 LHS,
RHS, IsAnd,
A,
B,
C,
D, E, PredL, PredR, LHSMask, RHSMask,
555 return Builder.
CreateICmp(NewCC, NewAnd, Zero);
564 return Builder.
CreateICmp(NewCC, NewAnd, NewOr);
579 const APInt *ConstB, *ConstD;
589 APInt NewMask = *ConstB & *ConstD;
590 if (NewMask == *ConstB)
592 else if (NewMask == *ConstD)
601 APInt NewMask = *ConstB | *ConstD;
602 if (NewMask == *ConstB)
604 else if (NewMask == *ConstD)
631 const APInt *OldConstC, *OldConstE;
637 const APInt ConstC = PredL !=
CC ? *ConstB ^ *OldConstC : *OldConstC;
638 const APInt ConstE = PredR !=
CC ? *ConstD ^ *OldConstE : *OldConstE;
640 if (((*ConstB & *ConstD) & (ConstC ^ ConstE)).getBoolValue())
641 return IsNot ? nullptr : ConstantInt::get(
LHS->
getType(), !IsAnd);
643 if (IsNot && !ConstB->
isSubsetOf(*ConstD) && !ConstD->isSubsetOf(*ConstB))
648 BD = *ConstB & *ConstD;
649 CE = ConstC & ConstE;
651 BD = *ConstB | *ConstD;
652 CE = ConstC | ConstE;
655 Value *CEVal = ConstantInt::get(
A->getType(), CE);
660 return FoldBMixed(NewCC,
false);
662 return FoldBMixed(NewCC,
true);
708 default:
return nullptr;
732 if (
LHS->getPredicate() != Pred ||
RHS->getPredicate() != Pred)
763Value *InstCombinerImpl::foldAndOrOfICmpsOfAndWithPow2(
ICmpInst *LHS,
769 if (
LHS->getPredicate() != Pred ||
RHS->getPredicate() != Pred)
779 if (L1 ==
R2 || L2 ==
R2)
837 auto tryToMatchSignedTruncationCheck = [](
ICmpInst *ICmp,
Value *&
X,
838 APInt &SignBitMask) ->
bool {
839 const APInt *I01, *I1;
843 I1->ugt(*I01) && I01->
shl(1) == *I1))
855 if (tryToMatchSignedTruncationCheck(ICmp1, X1, HighestBit))
857 else if (tryToMatchSignedTruncationCheck(ICmp0, X1, HighestBit))
862 assert(HighestBit.
isPowerOf2() &&
"expected to be power of two (non-zero)");
866 APInt &UnsetBitsMask) ->
bool {
870 Pred,
X, UnsetBitsMask,
878 UnsetBitsMask = *Mask;
887 if (!tryToDecompose(OtherICmp, X0, UnsetBitsMask))
890 assert(!UnsetBitsMask.
isZero() &&
"empty mask makes no sense.");
905 APInt SignBitsMask = ~(HighestBit - 1U);
912 if (!UnsetBitsMask.
isSubsetOf(SignBitsMask)) {
913 APInt OtherHighestBit = (~UnsetBitsMask) + 1U;
921 return Builder.
CreateICmpULT(
X, ConstantInt::get(
X->getType(), HighestBit),
922 CxtI.
getName() +
".simplified");
987 "Expected equality predicates for masked type of icmps.");
1007 const APInt *BCst, *DCst, *ECst;
1010 (isa<PoisonValue>(
B) ||
1015 if (
const auto *BVTy = dyn_cast<VectorType>(
B->getType())) {
1016 const auto *BFVTy = dyn_cast<FixedVectorType>(BVTy);
1017 const auto *BConst = dyn_cast<Constant>(
B);
1018 const auto *DConst = dyn_cast<Constant>(
D);
1019 const auto *EConst = dyn_cast<Constant>(E);
1021 if (!BFVTy || !BConst || !DConst || !EConst)
1024 for (
unsigned I = 0;
I != BFVTy->getNumElements(); ++
I) {
1025 const auto *BElt = BConst->getAggregateElement(
I);
1026 const auto *DElt = DConst->getAggregateElement(
I);
1027 const auto *EElt = EConst->getAggregateElement(
I);
1029 if (!BElt || !DElt || !EElt)
1031 if (!isReducible(BElt, DElt, EElt))
1036 if (!isReducible(
B,
D, E))
1054 Value *
A =
nullptr, *
B =
nullptr, *
C =
nullptr, *
D =
nullptr, *E =
nullptr;
1060 std::optional<std::pair<unsigned, unsigned>> MaskPair =
1066 unsigned CmpMask0 = MaskPair->first;
1067 unsigned CmpMask1 = MaskPair->second;
1068 if ((CmpMask0 &
Mask_AllZeros) && (CmpMask1 == compareBMask)) {
1072 }
else if ((CmpMask0 == compareBMask) && (CmpMask1 &
Mask_AllZeros)) {
1083 ICmpInst *UnsignedICmp,
bool IsAnd,
1095 if (
match(UnsignedICmp,
1111 IsAnd && GetKnownNonZeroAndOther(
B,
A))
1114 !IsAnd && GetKnownNonZeroAndOther(
B,
A))
1131 return std::nullopt;
1133 unsigned NumOriginalBits =
X->getType()->getScalarSizeInBits();
1134 unsigned NumExtractedBits = V->getType()->getScalarSizeInBits();
1140 Shift->
ule(NumOriginalBits - NumExtractedBits))
1142 return {{
X, 0, NumExtractedBits}};
1150 Type *TruncTy = V->getType()->getWithNewBitWidth(
P.NumBits);
1151 if (TruncTy != V->getType())
1166 unsigned OpNo) -> std::optional<IntPart> {
1167 if (Pred ==
Cmp->getPredicate())
1176 return std::nullopt;
1185 return std::nullopt;
1187 return std::nullopt;
1192 return {{
I->getOperand(OpNo),
From,
C->getBitWidth() -
From}};
1195 std::optional<IntPart> L0 = GetMatchPart(Cmp0, 0);
1196 std::optional<IntPart> R0 = GetMatchPart(Cmp0, 1);
1197 std::optional<IntPart> L1 = GetMatchPart(Cmp1, 0);
1198 std::optional<IntPart> R1 = GetMatchPart(Cmp1, 1);
1199 if (!L0 || !R0 || !L1 || !R1)
1204 if (L0->From != L1->From || R0->From != R1->From) {
1205 if (L0->From != R1->From || R0->From != L1->From)
1212 if (L0->StartBit + L0->NumBits != L1->StartBit ||
1213 R0->StartBit + R0->NumBits != R1->StartBit) {
1214 if (L1->StartBit + L1->NumBits != L0->StartBit ||
1215 R1->StartBit + R1->NumBits != R0->StartBit)
1222 IntPart L = {L0->From, L0->StartBit, L0->NumBits + L1->NumBits};
1223 IntPart R = {R0->From, R0->StartBit, R0->NumBits + R1->NumBits};
1233 bool IsAnd,
bool IsLogical,
1262 if (!SubstituteCmp) {
1272 return Builder.
CreateBinOp(IsAnd ? Instruction::And : Instruction::Or, Cmp0,
1280Value *InstCombinerImpl::foldAndOrOfICmpsUsingRanges(
ICmpInst *ICmp1,
1285 const APInt *C1, *C2;
1292 const APInt *Offset1 =
nullptr, *Offset2 =
nullptr;
1327 if (!LowerDiff.
isPowerOf2() || LowerDiff != UpperDiff ||
1340 CR->getEquivalentICmp(NewPred, NewC,
Offset);
1372 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1373 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1382 FMF &=
RHS->getFastMathFlags();
1389 bool IsAnd,
bool IsLogicalSelect) {
1390 Value *LHS0 =
LHS->getOperand(0), *LHS1 =
LHS->getOperand(1);
1391 Value *RHS0 =
RHS->getOperand(0), *RHS1 =
RHS->getOperand(1);
1394 if (LHS0 == RHS1 && RHS0 == LHS1) {
1414 if (LHS0 == RHS0 && LHS1 == RHS1) {
1417 unsigned NewPred = IsAnd ? FCmpCodeL & FCmpCodeR : FCmpCodeL | FCmpCodeR;
1423 FMF &=
RHS->getFastMathFlags();
1430 if (!IsLogicalSelect &&
1461 auto [ClassValRHS, ClassMaskRHS] =
1464 auto [ClassValLHS, ClassMaskLHS] =
1466 if (ClassValLHS == ClassValRHS) {
1467 unsigned CombinedMask = IsAnd ? (ClassMaskLHS & ClassMaskRHS)
1468 : (ClassMaskLHS | ClassMaskRHS);
1470 Intrinsic::is_fpclass, {ClassValLHS->getType()},
1499 if (IsLessThanOrLessEqual(IsAnd ? PredR : PredL)) {
1503 if (IsLessThanOrLessEqual(IsAnd ? PredL : PredR)) {
1506 RHS->getFastMathFlags());
1510 ConstantFP::get(LHS0->
getType(), *LHSC));
1521 auto *FCmp = dyn_cast<FCmpInst>(
Op);
1522 if (!FCmp || !FCmp->hasOneUse())
1525 std::tie(ClassVal, ClassMask) =
1526 fcmpToClassTest(FCmp->getPredicate(), *FCmp->getParent()->getParent(),
1527 FCmp->getOperand(0), FCmp->getOperand(1));
1528 return ClassVal !=
nullptr;
1539 Value *ClassVal0 =
nullptr;
1540 Value *ClassVal1 =
nullptr;
1557 ClassVal0 == ClassVal1) {
1558 unsigned NewClassMask;
1560 case Instruction::And:
1561 NewClassMask = ClassMask0 & ClassMask1;
1563 case Instruction::Or:
1564 NewClassMask = ClassMask0 | ClassMask1;
1566 case Instruction::Xor:
1567 NewClassMask = ClassMask0 ^ ClassMask1;
1574 auto *
II = cast<IntrinsicInst>(Op0);
1576 1, ConstantInt::get(
II->getArgOperand(1)->getType(), NewClassMask));
1581 auto *
II = cast<IntrinsicInst>(Op1);
1583 1, ConstantInt::get(
II->getArgOperand(1)->getType(), NewClassMask));
1603Instruction *InstCombinerImpl::canonicalizeConditionalNegationViaMathToSelect(
1605 assert(
I.getOpcode() == BinaryOperator::Xor &&
"Only for xor!");
1610 !
Cond->getType()->isIntOrIntVectorTy(1) ||
1624 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1625 "Expecting and/or op for fcmp transform");
1644 X->getType() !=
Y->getType())
1648 X->getType() !=
Y->getType())
1654 if (
auto *NewFCmpInst = dyn_cast<FCmpInst>(NewFCmp)) {
1656 NewFCmpInst->copyIRFlags(Op0);
1657 NewFCmpInst->andIRFlags(BO10);
1668 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
1669 "Trying to match De Morgan's Laws with something other than and/or");
1673 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1675 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1701bool InstCombinerImpl::shouldOptimizeCast(
CastInst *CI) {
1710 if (
const auto *PrecedingCI = dyn_cast<CastInst>(CastSrc))
1711 if (isEliminableCastPair(PrecedingCI, CI))
1737 return new ZExtInst(NewOp, DestTy);
1745 return new SExtInst(NewOp, DestTy);
1754 auto LogicOpc =
I.getOpcode();
1755 assert(
I.isBitwiseLogicOp() &&
"Unexpected opcode for bitwise logic folding");
1757 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1763 auto FoldBitwiseICmpZeroWithICmp = [&](
Value *Op0,
1778 auto *ICmpR = cast<ZExtInst>(Op1)->getOperand(0);
1784 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op0, Op1))
1787 if (
auto *Ret = FoldBitwiseICmpZeroWithICmp(Op1, Op0))
1790 CastInst *Cast0 = dyn_cast<CastInst>(Op0);
1796 Type *DestTy =
I.getType();
1804 CastInst *Cast1 = dyn_cast<CastInst>(Op1);
1821 unsigned XNumBits =
X->getType()->getScalarSizeInBits();
1822 unsigned YNumBits =
Y->getType()->getScalarSizeInBits();
1823 if (XNumBits < YNumBits)
1841 shouldOptimizeCast(Cast0) && shouldOptimizeCast(Cast1)) {
1852 assert(
I.getOpcode() == Instruction::And);
1853 Value *Op0 =
I.getOperand(0);
1854 Value *Op1 =
I.getOperand(1);
1862 return BinaryOperator::CreateXor(
A,
B);
1878 assert(
I.getOpcode() == Instruction::Or);
1879 Value *Op0 =
I.getOperand(0);
1880 Value *Op1 =
I.getOperand(1);
1905 return BinaryOperator::CreateXor(
A,
B);
1925 Value *Op0 =
And.getOperand(0), *Op1 =
And.getOperand(1);
1939 if (!isa<VectorType>(Ty) && !shouldChangeType(Ty,
X->getType()))
1946 if (Opc == Instruction::LShr || Opc == Instruction::Shl)
1963 assert(Opcode == Instruction::And || Opcode == Instruction::Or);
1967 (Opcode == Instruction::And) ? Instruction::Or : Instruction::And;
1969 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1976 const auto matchNotOrAnd =
1977 [Opcode, FlippedOpcode](
Value *
Op,
auto m_A,
auto m_B,
auto m_C,
1978 Value *&
X,
bool CountUses =
false) ->
bool {
1979 if (CountUses && !
Op->hasOneUse())
1986 return !CountUses ||
X->hasOneUse();
2002 return (Opcode == Instruction::Or)
2012 return (Opcode == Instruction::Or)
2035 if (Opcode == Instruction::Or && Op0->
hasOneUse() &&
2042 Value *
Or = cast<BinaryOperator>(
X)->getOperand(0);
2074 return (Opcode == Instruction::Or)
2076 : BinaryOperator::CreateOr(
Xor,
X);
2110 if (!isa<Constant>(
X) && !isa<Constant>(
Y) && !isa<Constant>(Z)) {
2112 if (!
X->hasOneUse()) {
2117 if (!
Y->hasOneUse()) {
2138 Type *Ty =
I.getType();
2140 Value *Op0 =
I.getOperand(0);
2141 Value *Op1 =
I.getOperand(1);
2153 case Instruction::And:
2154 if (
C->countl_one() < LastOneMath)
2157 case Instruction::Xor:
2158 case Instruction::Or:
2159 if (
C->countl_zero() < LastOneMath)
2168 ConstantInt::get(Ty, *C2), Op0);
2175 assert((
I.isBitwiseLogicOp() ||
I.getOpcode() == Instruction::Add) &&
2176 "Unexpected opcode");
2179 Constant *ShiftedC1, *ShiftedC2, *AddC;
2180 Type *Ty =
I.getType();
2194 auto *Op0Inst = dyn_cast<Instruction>(
I.getOperand(0));
2195 auto *Op1Inst = dyn_cast<Instruction>(
I.getOperand(1));
2196 if (!Op0Inst || !Op1Inst)
2202 if (ShiftOp != Op1Inst->getOpcode())
2206 if (
I.getOpcode() == Instruction::Add && ShiftOp != Instruction::Shl)
2226 assert(
I.isBitwiseLogicOp() &&
"Should and/or/xor");
2227 if (!
I.getOperand(0)->hasOneUse())
2234 if (
Y && (!
Y->hasOneUse() ||
X->getIntrinsicID() !=
Y->getIntrinsicID()))
2240 if (!
Y && (!(IID == Intrinsic::bswap || IID == Intrinsic::bitreverse) ||
2245 case Intrinsic::fshl:
2246 case Intrinsic::fshr: {
2247 if (
X->getOperand(2) !=
Y->getOperand(2))
2250 Builder.
CreateBinOp(
I.getOpcode(),
X->getOperand(0),
Y->getOperand(0));
2252 Builder.
CreateBinOp(
I.getOpcode(),
X->getOperand(1),
Y->getOperand(1));
2256 case Intrinsic::bswap:
2257 case Intrinsic::bitreverse: {
2259 I.getOpcode(),
X->getOperand(0),
2260 Y ?
Y->getOperand(0)
2261 : ConstantInt::get(
I.getType(), IID == Intrinsic::bswap
2280 unsigned Depth = 0) {
2287 auto *
I = dyn_cast<BinaryOperator>(V);
2288 if (!
I || !
I->isBitwiseLogicOp() ||
Depth >= 3)
2291 if (!
I->hasOneUse())
2292 SimplifyOnly =
true;
2295 SimplifyOnly, IC,
Depth + 1);
2297 SimplifyOnly, IC,
Depth + 1);
2298 if (!NewOp0 && !NewOp1)
2302 NewOp0 =
I->getOperand(0);
2304 NewOp1 =
I->getOperand(1);
2319 Type *Ty =
I.getType();
2353 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
2388 Constant *NewC = ConstantInt::get(Ty, *
C & *XorC);
2391 return BinaryOperator::CreateXor(
And, NewC);
2402 APInt Together = *
C & *OrC;
2405 return BinaryOperator::CreateOr(
And, ConstantInt::get(Ty, Together));
2409 const APInt *ShiftC;
2411 ShiftC->
ult(Width)) {
2416 Constant *ShAmtC = ConstantInt::get(Ty, ShiftC->
zext(Width));
2417 return BinaryOperator::CreateLShr(Sext, ShAmtC);
2425 return BinaryOperator::CreateLShr(
X, ConstantInt::get(Ty, *ShiftC));
2433 if (Op0->
hasOneUse() &&
C->isPowerOf2() && (*AddC & (*
C - 1)) == 0) {
2434 assert((*
C & *AddC) != 0 &&
"Expected common bit");
2436 return BinaryOperator::CreateXor(NewAnd, Op1);
2443 switch (
B->getOpcode()) {
2444 case Instruction::Xor:
2445 case Instruction::Or:
2446 case Instruction::Mul:
2447 case Instruction::Add:
2448 case Instruction::Sub:
2464 C->isIntN(
X->getType()->getScalarSizeInBits())) {
2465 unsigned XWidth =
X->getType()->getScalarSizeInBits();
2466 Constant *TruncC1 = ConstantInt::get(
X->getType(), C1->
trunc(XWidth));
2470 Constant *TruncC = ConstantInt::get(
X->getType(),
C->trunc(XWidth));
2480 C->isMask(
X->getType()->getScalarSizeInBits())) {
2490 C->isMask(
X->getType()->getScalarSizeInBits())) {
2524 if (
C->isPowerOf2() &&
2527 int Log2C =
C->exactLogBase2();
2529 cast<BinaryOperator>(Op0)->getOpcode() == Instruction::Shl;
2530 int BitNum = IsShiftLeft ? Log2C - Log2ShiftC : Log2ShiftC - Log2C;
2531 assert(BitNum >= 0 &&
"Expected demanded bits to handle impossible mask");
2564 if (Cmp && Cmp->isZeroValue()) {
2589 Attribute::NoImplicitFloat)) {
2605 X->getType()->getScalarSizeInBits())))) {
2607 return BinaryOperator::CreateAnd(SExt, Op1);
2613 if (
I.getType()->isIntOrIntVectorTy(1)) {
2614 if (
auto *SI0 = dyn_cast<SelectInst>(Op0)) {
2616 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
true))
2619 if (
auto *SI1 = dyn_cast<SelectInst>(Op1)) {
2621 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
true))
2636 return BinaryOperator::CreateAnd(Op0,
B);
2639 return BinaryOperator::CreateAnd(Op1,
B);
2647 if (NotC !=
nullptr)
2648 return BinaryOperator::CreateAnd(Op0, NotC);
2657 if (NotC !=
nullptr)
2667 return BinaryOperator::CreateAnd(
A,
B);
2675 return BinaryOperator::CreateAnd(
A,
B);
2704 bool IsLogical = isa<SelectInst>(Op1);
2706 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
2708 foldAndOrOfICmps(
LHS, Cmp,
I,
true, IsLogical))
2713 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
2714 if (
Value *Res = foldAndOrOfICmps(
LHS, Cmp,
I,
true,
2721 bool IsLogical = isa<SelectInst>(Op0);
2723 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
2725 foldAndOrOfICmps(Cmp,
RHS,
I,
true, IsLogical))
2730 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
2731 if (
Value *Res = foldAndOrOfICmps(Cmp,
RHS,
I,
true,
2739 if (
FCmpInst *
LHS = dyn_cast<FCmpInst>(
I.getOperand(0)))
2740 if (
FCmpInst *
RHS = dyn_cast<FCmpInst>(
I.getOperand(1)))
2741 if (
Value *Res = foldLogicOfFCmps(
LHS,
RHS,
true))
2747 if (
Instruction *CastedAnd = foldCastedBitwiseLogic(
I))
2760 A->getType()->isIntOrIntVectorTy(1))
2766 A->getType()->isIntOrIntVectorTy(1))
2771 A->getType()->isIntOrIntVectorTy(1))
2778 if (
A->getType()->isIntOrIntVectorTy(1))
2791 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2800 *
C ==
X->getType()->getScalarSizeInBits() - 1) {
2811 Value *Start =
nullptr, *Step =
nullptr;
2819 return Canonicalized;
2821 if (
Instruction *Folded = foldLogicOfIsFPClass(
I, Op0, Op1))
2833 return BinaryOperator::CreateAnd(V, Op1);
2837 return BinaryOperator::CreateAnd(Op0, V);
2844 bool MatchBitReversals) {
2852 for (
auto *Inst : Insts)
2857std::optional<std::pair<Intrinsic::ID, SmallVector<Value *, 3>>>
2861 assert(
Or.getOpcode() == BinaryOperator::Or &&
"Expecting or instruction");
2863 unsigned Width =
Or.getType()->getScalarSizeInBits();
2868 return std::nullopt;
2875 if (isa<BinaryOperator>(Or0) && isa<BinaryOperator>(Or1)) {
2876 Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
2882 return std::nullopt;
2885 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2891 Or1->
getOpcode() == BinaryOperator::LShr &&
2892 "Illegal or(shift,shift) pair");
2896 auto matchShiftAmount = [&](
Value *L,
Value *R,
unsigned Width) ->
Value * {
2900 if (
LI->ult(Width) && RI->
ult(Width) && (*
LI + *RI) == Width)
2901 return ConstantInt::get(L->getType(), *
LI);
2925 if (ShVal0 != ShVal1)
2936 unsigned Mask = Width - 1;
2960 Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, Width);
2962 ShAmt = matchShiftAmount(ShAmt1, ShAmt0, Width);
2966 return std::nullopt;
2968 FShiftArgs = {ShVal0, ShVal1, ShAmt};
2969 }
else if (isa<ZExtInst>(Or0) || isa<ZExtInst>(Or1)) {
2981 if (!isa<ZExtInst>(Or1))
2985 const APInt *ZextHighShlAmt;
2988 return std::nullopt;
2992 return std::nullopt;
2994 unsigned HighSize =
High->getType()->getScalarSizeInBits();
2995 unsigned LowSize =
Low->getType()->getScalarSizeInBits();
2998 if (ZextHighShlAmt->
ult(LowSize) || ZextHighShlAmt->
ugt(Width - HighSize))
2999 return std::nullopt;
3006 if (!isa<ZExtInst>(
Y))
3009 const APInt *ZextLowShlAmt;
3016 if (*ZextLowShlAmt + *ZextHighShlAmt != Width)
3022 ZextLowShlAmt->
ule(Width - LowSize) &&
"Invalid concat");
3024 FShiftArgs = {U, U, ConstantInt::get(Or0->
getType(), *ZextHighShlAmt)};
3029 if (FShiftArgs.
empty())
3030 return std::nullopt;
3032 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
3033 return std::make_pair(IID, FShiftArgs);
3039 auto [IID, FShiftArgs] = *Opt;
3050 assert(
Or.getOpcode() == Instruction::Or &&
"bswap requires an 'or'");
3051 Value *Op0 =
Or.getOperand(0), *Op1 =
Or.getOperand(1);
3055 if ((Width & 1) != 0)
3057 unsigned HalfWidth = Width / 2;
3060 if (!isa<ZExtInst>(Op0))
3064 Value *LowerSrc, *ShlVal, *UpperSrc;
3077 NewUpper = Builder.
CreateShl(NewUpper, HalfWidth);
3085 Value *LowerBSwap, *UpperBSwap;
3088 return ConcatIntrinsicCalls(Intrinsic::bswap, UpperBSwap, LowerBSwap);
3092 Value *LowerBRev, *UpperBRev;
3095 return ConcatIntrinsicCalls(Intrinsic::bitreverse, UpperBRev, LowerBRev);
3102 unsigned NumElts = cast<FixedVectorType>(C1->
getType())->getNumElements();
3103 for (
unsigned i = 0; i != NumElts; ++i) {
3106 if (!EltC1 || !EltC2)
3125 Type *Ty =
A->getType();
3141 if (
A->getType()->isIntOrIntVectorTy()) {
3143 if (NumSignBits ==
A->getType()->getScalarSizeInBits() &&
3166 Cond->getType()->isIntOrIntVectorTy(1)) {
3192 Cond->getType()->isIntOrIntVectorTy(1) &&
3206 Value *
D,
bool InvertFalseVal) {
3209 Type *OrigType =
A->getType();
3212 if (
Value *
Cond = getSelectCondition(
A,
C, InvertFalseVal)) {
3217 Type *SelTy =
A->getType();
3218 if (
auto *VecTy = dyn_cast<VectorType>(
Cond->getType())) {
3220 unsigned Elts = VecTy->getElementCount().getKnownMinValue();
3241 bool IsAnd,
bool IsLogical,
3248 IsAnd ?
LHS->getInversePredicate() :
LHS->getPredicate();
3250 IsAnd ?
RHS->getInversePredicate() :
RHS->getPredicate();
3259 auto MatchRHSOp = [LHS0, CInt](
const Value *RHSOp) {
3262 (CInt->
isZero() && RHSOp == LHS0);
3293 if (
Value *V = foldAndOrOfICmpsOfAndWithPow2(LHS, RHS, &
I, IsAnd, IsLogical))
3297 Value *LHS0 =
LHS->getOperand(0), *RHS0 =
RHS->getOperand(0);
3298 Value *LHS1 =
LHS->getOperand(1), *RHS1 =
RHS->getOperand(1);
3300 const APInt *LHSC =
nullptr, *RHSC =
nullptr;
3307 if (LHS0 == RHS1 && LHS1 == RHS0) {
3311 if (LHS0 == RHS0 && LHS1 == RHS1) {
3314 bool IsSigned =
LHS->isSigned() ||
RHS->isSigned();
3363 if (IsAnd && !IsLogical)
3381 if (
Value *
X = foldEqOfParts(LHS, RHS, IsAnd))
3421 const APInt *AndC, *SmallC =
nullptr, *BigC =
nullptr;
3435 if (SmallC && BigC) {
3436 unsigned BigBitSize = BigC->getBitWidth();
3455 bool TrueIfSignedL, TrueIfSignedR;
3461 if ((TrueIfSignedL && !TrueIfSignedR &&
3464 (!TrueIfSignedL && TrueIfSignedR &&
3471 if ((TrueIfSignedL && !TrueIfSignedR &&
3474 (!TrueIfSignedL && TrueIfSignedR &&
3483 return foldAndOrOfICmpsUsingRanges(LHS, RHS, IsAnd);
3488 assert(
I.getOpcode() == Instruction::Or &&
3489 "Simplification only supports or at the moment.");
3491 Value *Cmp1, *Cmp2, *Cmp3, *Cmp4;
3543 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
3544 Type *Ty =
I.getType();
3546 if (
auto *SI0 = dyn_cast<SelectInst>(Op0)) {
3548 foldAndOrOfSelectUsingImpliedCond(Op1, *SI0,
false))
3551 if (
auto *SI1 = dyn_cast<SelectInst>(Op1)) {
3553 foldAndOrOfSelectUsingImpliedCond(Op0, *SI1,
false))
3584 return BinaryOperator::CreateXor(
Or, ConstantInt::get(Ty, *CV));
3592 return BinaryOperator::CreateMul(
X, IncrementY);
3601 const APInt *C0, *C1;
3620 if ((*C0 & *C1).
isZero()) {
3625 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
3626 return BinaryOperator::CreateAnd(
A, C01);
3632 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
3633 return BinaryOperator::CreateAnd(
B, C01);
3637 const APInt *C2, *C3;
3642 Constant *C01 = ConstantInt::get(Ty, *C0 | *C1);
3643 return BinaryOperator::CreateAnd(
Or, C01);
3653 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D))
3655 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B))
3657 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D))
3659 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B))
3661 if (
Value *V = matchSelectFromAndOr(
B,
D,
A,
C))
3663 if (
Value *V = matchSelectFromAndOr(
B,
D,
C,
A))
3665 if (
Value *V = matchSelectFromAndOr(
D,
B,
A,
C))
3667 if (
Value *V = matchSelectFromAndOr(
D,
B,
C,
A))
3676 if (
Value *V = matchSelectFromAndOr(
A,
C,
B,
D,
true))
3678 if (
Value *V = matchSelectFromAndOr(
A,
C,
D,
B,
true))
3680 if (
Value *V = matchSelectFromAndOr(
C,
A,
B,
D,
true))
3682 if (
Value *V = matchSelectFromAndOr(
C,
A,
D,
B,
true))
3691 return BinaryOperator::CreateOr(Op0,
C);
3698 return BinaryOperator::CreateOr(Op1,
C);
3704 bool SwappedForXor =
false;
3707 SwappedForXor =
true;
3714 return BinaryOperator::CreateOr(Op0,
B);
3716 return BinaryOperator::CreateOr(Op0,
A);
3721 return BinaryOperator::CreateOr(
A,
B);
3749 return BinaryOperator::CreateOr(Nand,
C);
3767 bool IsLogical = isa<SelectInst>(Op1);
3769 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
3771 foldAndOrOfICmps(
LHS, Cmp,
I,
false, IsLogical))
3776 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
3777 if (
Value *Res = foldAndOrOfICmps(
LHS, Cmp,
I,
false,
3784 bool IsLogical = isa<SelectInst>(Op0);
3786 if (
auto *Cmp = dyn_cast<ICmpInst>(
X))
3788 foldAndOrOfICmps(Cmp,
RHS,
I,
false, IsLogical))
3793 if (
auto *Cmp = dyn_cast<ICmpInst>(
Y))
3794 if (
Value *Res = foldAndOrOfICmps(Cmp,
RHS,
I,
false,
3802 if (
FCmpInst *
LHS = dyn_cast<FCmpInst>(
I.getOperand(0)))
3803 if (
FCmpInst *
RHS = dyn_cast<FCmpInst>(
I.getOperand(1)))
3804 if (
Value *Res = foldLogicOfFCmps(
LHS,
RHS,
false))
3822 A->getType()->isIntOrIntVectorTy(1))
3835 return BinaryOperator::CreateOr(Inner, CI);
3842 Value *
X =
nullptr, *
Y =
nullptr;