46#define DEBUG_TYPE "instcombine"
50using namespace PatternMatch;
67 IsEq = Pred == ICmpInst::ICMP_EQ;
68 else if (Pred == FCmpInst::FCMP_OEQ)
70 else if (Pred == FCmpInst::FCMP_UNE)
100 if (isa<FPMathOperator>(BO))
124 const APInt *SelTC, *SelFC;
131 if (SelType->
isVectorTy() != Cmp->getType()->isVectorTy())
136 bool CreateAnd =
false;
142 V = Cmp->getOperand(0);
149 Cmp->getOperand(1), Pred)) {
151 if (!Res->Mask.isPowerOf2())
161 if (Pred == ICmpInst::ICMP_NE)
168 const APInt &TC = *SelTC;
169 const APInt &FC = *SelFC;
170 if (!TC.
isZero() && !FC.isZero()) {
175 if (CreateAnd && !Cmp->hasOneUse())
182 Constant *TCC = ConstantInt::get(SelType, TC);
183 Constant *FCC = ConstantInt::get(SelType, FC);
184 Constant *MaskC = ConstantInt::get(SelType, AndMask);
185 for (
auto Opc : {Instruction::Or, Instruction::Xor, Instruction::Add,
205 unsigned ValZeros = ValC.
logBase2();
206 unsigned AndZeros = AndMask.
logBase2();
207 bool ShouldNotVal = !TC.
isZero();
212 if (CreateAnd && ShouldNotVal && ValZeros != AndZeros)
217 V = Builder.
CreateAnd(V, ConstantInt::get(V->getType(), AndMask));
221 if (ValZeros > AndZeros) {
223 V = Builder.
CreateShl(V, ValZeros - AndZeros);
224 }
else if (ValZeros < AndZeros) {
225 V = Builder.
CreateLShr(V, AndZeros - ValZeros);
250 switch (
I->getOpcode()) {
251 case Instruction::Add:
252 case Instruction::FAdd:
253 case Instruction::Mul:
254 case Instruction::FMul:
255 case Instruction::And:
256 case Instruction::Or:
257 case Instruction::Xor:
259 case Instruction::Sub:
260 case Instruction::FSub:
261 case Instruction::FDiv:
262 case Instruction::Shl:
263 case Instruction::LShr:
264 case Instruction::AShr:
294 if (
auto *CondVTy = dyn_cast<VectorType>(CondTy)) {
296 CondVTy->getElementCount() !=
297 cast<VectorType>(FIOpndTy)->getElementCount())
308 if (TI->
getOpcode() != Instruction::BitCast &&
321 SI.getName() +
".v", &SI);
326 Value *OtherOpT, *OtherOpF;
329 bool Swapped =
false) ->
Value * {
330 assert(!(Commute && Swapped) &&
331 "Commute and Swapped can't set at the same time");
336 MatchIsOpZero =
true;
341 MatchIsOpZero =
false;
346 if (!Commute && !Swapped)
355 MatchIsOpZero =
true;
360 MatchIsOpZero =
false;
374 FMF |= SI.getFastMathFlags();
377 if (
auto *NewSelI = dyn_cast<Instruction>(NewSel))
378 NewSelI->setFastMathFlags(FMF);
379 Instruction *NewFNeg = UnaryOperator::CreateFNeg(NewSel);
388 auto *
TII = dyn_cast<IntrinsicInst>(TI);
389 auto *FII = dyn_cast<IntrinsicInst>(FI);
390 if (
TII && FII &&
TII->getIntrinsicID() == FII->getIntrinsicID()) {
392 if (
Value *MatchOp = getCommonOp(TI, FI,
true)) {
404 if (
TII->getIntrinsicID() == Intrinsic::ldexp) {
405 Value *LdexpVal0 =
TII->getArgOperand(0);
406 Value *LdexpExp0 =
TII->getArgOperand(1);
407 Value *LdexpVal1 = FII->getArgOperand(0);
408 Value *LdexpExp1 = FII->getArgOperand(1);
412 FMF &= cast<FPMathOperator>(FII)->getFastMathFlags();
419 TII->
getType(), Intrinsic::ldexp, {SelectVal, SelectExp});
434 bool Swapped =
T !=
F;
438 SI.getName() +
".v", &SI);
453 (!isa<BinaryOperator>(TI) && !isa<GetElementPtrInst>(TI)) ||
475 auto *BO = dyn_cast<BinaryOperator>(TI);
479 if (BO->getOpcode() == Instruction::SDiv ||
480 BO->getOpcode() == Instruction::SRem || MatchIsOpZero)
486 SI.getName() +
".v", &SI);
487 Value *Op0 = MatchIsOpZero ? MatchOp : NewSI;
488 Value *Op1 = MatchIsOpZero ? NewSI : MatchOp;
489 if (
auto *BO = dyn_cast<BinaryOperator>(TI)) {
495 if (
auto *TGEP = dyn_cast<GetElementPtrInst>(TI)) {
496 auto *FGEP = cast<GetElementPtrInst>(FI);
497 Type *ElementType = TGEP->getSourceElementType();
499 ElementType, Op0, Op1, TGEP->getNoWrapFlags() & FGEP->getNoWrapFlags());
520 auto *TVI = dyn_cast<BinaryOperator>(TrueVal);
521 if (!TVI || !TVI->hasOneUse() || isa<Constant>(FalseVal))
525 unsigned OpToFold = 0;
526 if ((SFO & 1) && FalseVal == TVI->getOperand(0))
528 else if ((SFO & 2) && FalseVal == TVI->getOperand(1))
535 if (isa<FPMathOperator>(&SI))
536 FMF = SI.getFastMathFlags();
538 TVI->getOpcode(), TVI->getType(),
true, FMF.
noSignedZeros());
539 Value *OOp = TVI->getOperand(2 - OpToFold);
544 if (isa<Constant>(OOp) &&
545 (!OOpIsAPInt || !
isSelect01(
C->getUniqueInteger(), *OOpC)))
554 if (isa<FPMathOperator>(&SI) &&
559 Swapped ? OOp :
C,
"", &SI);
560 if (isa<FPMathOperator>(&SI))
561 cast<Instruction>(NewSel)->setFastMathFlags(FMF);
566 if (isa<FPMathOperator>(&SI)) {
577 if (
Instruction *R = TryFoldSelectIntoOp(SI, TrueVal, FalseVal,
false))
580 if (
Instruction *R = TryFoldSelectIntoOp(SI, FalseVal, TrueVal,
true))
597 if (!(Cmp->hasOneUse() && Cmp->getOperand(0)->hasOneUse() &&
629 Constant *One = ConstantInt::get(SelType, 1);
634 return new ZExtInst(ICmpNeZero, SelType);
656 const APInt *C2, *C1;
666 auto *FI = dyn_cast<Instruction>(FVal);
670 FI->setHasNoSignedWrap(
false);
671 FI->setHasNoUnsignedWrap(
false);
706 const auto *Ashr = cast<Instruction>(FalseVal);
708 bool IsExact = Ashr->isExact() && cast<Instruction>(TrueVal)->isExact();
740 if (!TrueVal->getType()->isIntOrIntVectorTy() ||
761 if (!Res || !Res->Mask.isPowerOf2())
766 C1Log = Res->Mask.logBase2();
776 BinOp = cast<BinaryOperator>(FalseVal);
780 BinOp = cast<BinaryOperator>(TrueVal);
790 if (IdentityC ==
nullptr || !IdentityC->isNullValue())
795 bool NeedShift = C1Log != C2Log;
796 bool NeedZExtTrunc =
Y->getType()->getScalarSizeInBits() !=
797 V->getType()->getScalarSizeInBits();
800 if ((NeedShift + NeedXor + NeedZExtTrunc +
NeedAnd) >
807 V = Builder.
CreateAnd(V, ConstantInt::get(V->getType(), C1));
813 }
else if (C1Log > C2Log) {
840 Constant *OrC = ConstantInt::get(Ty, *
C);
842 return BinaryOperator::CreateOr(
T, NewSel);
849 Constant *OrC = ConstantInt::get(Ty, *
C);
851 return BinaryOperator::CreateOr(
F, NewSel);
868 auto *CondVal = SI.getCondition();
869 auto *TrueVal = SI.getTrueValue();
870 auto *FalseVal = SI.getFalseValue();
888 auto *TrueValC = dyn_cast<Constant>(TrueVal);
889 if (TrueValC ==
nullptr ||
891 !isa<Instruction>(FalseVal))
894 auto *ZeroC = cast<Constant>(cast<Instruction>(CondVal)->getOperand(1));
902 auto *FalseValI = cast<Instruction>(FalseVal);
905 IC.
replaceOperand(*FalseValI, FalseValI->getOperand(0) ==
Y ? 0 : 1, FrY);
912 const Value *TrueVal,
913 const Value *FalseVal,
934 ConstantInt::get(
A->getType(), 1));
948 "Unexpected isUnsigned predicate!");
954 bool IsNegative =
false;
967 if (IsNegative && !TrueVal->hasOneUse() && !ICI->
hasOneUse())
980 if (!Cmp->hasOneUse())
984 Value *Cmp0 = Cmp->getOperand(0);
985 Value *Cmp1 = Cmp->getOperand(1);
1006 Intrinsic::uadd_sat, Cmp0, ConstantInt::get(Cmp0->
getType(), 1));
1017 ConstantInt::get(Cmp0->
getType(), *
C));
1027 ConstantInt::get(Cmp0->
getType(), *
C));
1037 ConstantInt::get(Cmp0->
getType(), *
C));
1084 auto *TI = dyn_cast<Instruction>(TVal);
1085 auto *FI = dyn_cast<Instruction>(FVal);
1091 Value *
A = Cmp->getOperand(0);
1092 Value *
B = Cmp->getOperand(1);
1105 (TI->hasNoSignedWrap() || TI->hasNoUnsignedWrap()) &&
1106 (FI->hasNoSignedWrap() || FI->hasNoUnsignedWrap())) {
1113 TI->setHasNoUnsignedWrap(
false);
1114 if (!TI->hasNoSignedWrap())
1115 TI->setHasNoSignedWrap(TI->hasOneUse());
1143 if (!
match(FalseVal,
1147 if (!
match(Ctlz, m_Intrinsic<Intrinsic::ctlz>()))
1154 auto *
II = cast<IntrinsicInst>(Ctlz);
1159 II->getModule(), Intrinsic::cttz,
II->getType());
1191 Value *Count =
nullptr;
1199 if (!
match(Count, m_Intrinsic<Intrinsic::cttz>(
m_Value(
X))) &&
1219 II->dropPoisonGeneratingAnnotations();
1231 II->dropUBImplyingAttrsAndMetadata();
1242 if (!
TrueVal->getType()->isIntOrIntVectorTy())
1279 assert(!isa<Constant>(Old) &&
"Only replace non-constant values");
1281 auto *
I = dyn_cast<Instruction>(V);
1282 if (!
I || !
I->hasOneUse() ||
1290 bool Changed =
false;
1291 for (
Use &U :
I->operands()) {
1324 bool Swapped =
false;
1325 if (
Cmp.isEquivalence(
true)) {
1328 }
else if (!
Cmp.isEquivalence()) {
1332 Value *CmpLHS =
Cmp.getOperand(0), *CmpRHS =
Cmp.getOperand(1);
1333 auto ReplaceOldOpWithNewOp = [&](
Value *OldOp,
1341 if (TrueVal == OldOp && (isa<Constant>(OldOp) || !isa<Constant>(NewOp)))
1376 if (
Instruction *R = ReplaceOldOpWithNewOp(CmpLHS, CmpRHS))
1378 if (
Instruction *R = ReplaceOldOpWithNewOp(CmpRHS, CmpLHS))
1381 auto *FalseInst = dyn_cast<Instruction>(FalseVal);
1396 &DropFlags) == TrueVal ||
1399 &DropFlags) == TrueVal) {
1401 I->dropPoisonGeneratingAnnotations();
1446 cast<ICmpInst>(XeqY)->setSameSign(
false);
1481 if (!isa<SelectInst>(Sel1)) {
1522 if (Cmp00->
getType() !=
X->getType() &&
X->hasOneUse())
1530 else if (!
match(Cmp00,
1538 Value *ReplacementLow, *ReplacementHigh;
1575 std::swap(ReplacementLow, ReplacementHigh);
1581 "Unexpected predicate type.");
1589 "Unexpected predicate type.");
1591 std::swap(ThresholdLowIncl, ThresholdHighExcl);
1607 if (
X->getType() != Sel0.
getType()) {
1617 assert(ReplacementLow && ReplacementHigh &&
1618 "Constant folding of ImmConstant cannot fail");
1624 Value *MaybeReplacedLow =
1630 ShouldReplaceHigh, ReplacementHigh, MaybeReplacedLow);
1674 Value *SelVal0, *SelVal1;
1683 auto MatchesSelectValue = [SelVal0, SelVal1](
Constant *
C) {
1684 return C->isElementWiseEqual(SelVal0) ||
C->isElementWiseEqual(SelVal1);
1688 if (MatchesSelectValue(C0))
1692 auto FlippedStrictness =
1694 if (!FlippedStrictness)
1698 if (!MatchesSelectValue(FlippedStrictness->second))
1707 Cmp.getName() +
".inv");
1718 if (!
Cmp->hasOneUse())
1748 Value *TVal =
SI.getTrueValue();
1749 Value *FVal =
SI.getFalseValue();
1775 const APInt *BinOpC;
1843 foldSelectWithExtremeEqCond(CmpLHS, CmpRHS, TrueVal, FalseVal))
1856 const unsigned AndOps = Instruction::And, OrOps = Instruction::Or,
1857 XorOps = Instruction::Xor, NoOps = 0;
1858 enum NotMask {
None = 0, NotInner, NotRHS };
1860 auto matchFalseVal = [&](
unsigned OuterOpc,
unsigned InnerOpc,
1863 if (OuterOpc == NoOps)
1866 if (NotMask == NotInner) {
1869 }
else if (NotMask == NotRHS) {
1873 return match(FalseVal,
1884 if (matchFalseVal(OrOps, XorOps,
None) ||
1885 matchFalseVal(XorOps, XorOps,
None))
1890 if (matchFalseVal(XorOps, OrOps,
None) ||
1891 matchFalseVal(AndOps, OrOps, NotRHS))
1902 if (matchFalseVal(XorOps, XorOps,
None) ||
1903 matchFalseVal(AndOps, XorOps, NotInner))
1908 if (matchFalseVal(XorOps, AndOps,
None) ||
1909 matchFalseVal(AndOps, AndOps, NotInner))
1920 if (matchFalseVal(XorOps, OrOps,
None) ||
1921 matchFalseVal(AndOps, OrOps, NotRHS))
1926 if (matchFalseVal(OrOps, AndOps,
None) ||
1927 matchFalseVal(XorOps, AndOps,
None))
1980 Opcode, Flipped->second, C2,
DL)) {
1982 RHS = Flipped->second;
1996 canonicalizeSPF(*ICI,
SI.getTrueValue(),
SI.getFalseValue(), *
this))
1999 if (
Value *V = foldSelectInstWithICmpConst(SI, ICI,
Builder))
2002 if (
Value *V = canonicalizeClampLike(SI, *ICI,
Builder, *
this))
2006 tryToReuseConstantFromSelectInComparison(SI, *ICI, *
this))
2013 bool Changed =
false;
2020 if (
Instruction *NewSel = foldSelectICmpEq(SI, ICI, *
this))
2035 SI.swapProfMetadata();
2058 if (
Value *V = foldSelectCttzCtlz(ICI, TrueVal, FalseVal, *
this))
2070 if (
Value *V = foldSelectWithConstOpToBinOp(ICI, TrueVal, FalseVal,
Builder))
2073 return Changed ? &
SI :
nullptr;
2086 if (
C ==
A ||
C ==
B) {
2101 Value *CondVal =
SI.getCondition();
2104 auto *TI = dyn_cast<Instruction>(TrueVal);
2105 auto *FI = dyn_cast<Instruction>(FalseVal);
2106 if (!TI || !FI || !TI->hasOneUse() || !FI->hasOneUse())
2110 if ((TI->getOpcode() == Instruction::Sub &&
2111 FI->getOpcode() == Instruction::Add) ||
2112 (TI->getOpcode() == Instruction::FSub &&
2113 FI->getOpcode() == Instruction::FAdd)) {
2116 }
else if ((FI->getOpcode() == Instruction::Sub &&
2117 TI->getOpcode() == Instruction::Add) ||
2118 (FI->getOpcode() == Instruction::FSub &&
2119 TI->getOpcode() == Instruction::FAdd)) {
2125 Value *OtherAddOp =
nullptr;
2126 if (SubOp->getOperand(0) == AddOp->
getOperand(0)) {
2128 }
else if (SubOp->getOperand(0) == AddOp->
getOperand(1)) {
2136 if (
SI.getType()->isFPOrFPVectorTy()) {
2137 NegVal = Builder.
CreateFNeg(SubOp->getOperand(1));
2138 if (
Instruction *NegInst = dyn_cast<Instruction>(NegVal)) {
2140 Flags &= SubOp->getFastMathFlags();
2141 NegInst->setFastMathFlags(Flags);
2144 NegVal = Builder.
CreateNeg(SubOp->getOperand(1));
2147 Value *NewTrueOp = OtherAddOp;
2148 Value *NewFalseOp = NegVal;
2152 SI.getName() +
".p", &SI);
2154 if (
SI.getType()->isFPOrFPVectorTy()) {
2156 BinaryOperator::CreateFAdd(SubOp->getOperand(0), NewSel);
2159 Flags &= SubOp->getFastMathFlags();
2163 return BinaryOperator::CreateAdd(SubOp->getOperand(0), NewSel);
2176 Value *CondVal =
SI.getCondition();
2188 auto IsSignedSaturateLimit = [&](
Value *Limit,
bool IsAdd) {
2198 auto IsZeroOrOne = [](
const APInt &
C) {
return C.isZero() ||
C.isOne(); };
2215 IsMinMax(TrueVal, FalseVal))
2222 IsMinMax(FalseVal, TrueVal))
2228 IsMinMax(TrueVal, FalseVal))
2233 IsMinMax(FalseVal, TrueVal))
2238 IsMinMax(FalseVal, TrueVal))
2243 IsMinMax(TrueVal, FalseVal))
2251 if (
II->getIntrinsicID() == Intrinsic::uadd_with_overflow &&
2254 NewIntrinsicID = Intrinsic::uadd_sat;
2255 else if (
II->getIntrinsicID() == Intrinsic::usub_with_overflow &&
2258 NewIntrinsicID = Intrinsic::usub_sat;
2259 else if (
II->getIntrinsicID() == Intrinsic::sadd_with_overflow &&
2260 IsSignedSaturateLimit(TrueVal,
true))
2269 NewIntrinsicID = Intrinsic::sadd_sat;
2270 else if (
II->getIntrinsicID() == Intrinsic::ssub_with_overflow &&
2271 IsSignedSaturateLimit(TrueVal,
false))
2280 NewIntrinsicID = Intrinsic::ssub_sat;
2285 NewIntrinsicID,
SI.getType());
2301 if (ExtOpcode != Instruction::ZExt && ExtOpcode != Instruction::SExt)
2307 Type *SmallType =
X->getType();
2309 auto *
Cmp = dyn_cast<CmpInst>(
Cond);
2311 (!Cmp ||
Cmp->getOperand(0)->getType() != SmallType))
2319 Value *TruncCVal = cast<Value>(TruncC);
2335 Value *CondVal =
SI.getCondition();
2337 auto *CondValTy = dyn_cast<FixedVectorType>(CondVal->
getType());
2341 unsigned NumElts = CondValTy->getNumElements();
2343 Mask.reserve(NumElts);
2344 for (
unsigned i = 0; i != NumElts; ++i) {
2354 Mask.push_back(i + NumElts);
2355 }
else if (isa<UndefValue>(Elt)) {
2375 auto *Ty = dyn_cast<VectorType>(Sel.
getType());
2407 if (TVal ==
A || TVal ==
B || FVal ==
A || FVal ==
B)
2424 if (TSrc ==
C && FSrc ==
D) {
2428 }
else if (TSrc ==
D && FSrc ==
C) {
2467 auto *Extract = dyn_cast<ExtractValueInst>(V);
2470 if (Extract->getIndices()[0] !=
I)
2472 return dyn_cast<AtomicCmpXchgInst>(Extract->getAggregateOperand());
2478 if (
auto *
Select = dyn_cast<SelectInst>(
SI.user_back()))
2479 if (
Select->getCondition() ==
SI.getCondition())
2480 if (
Select->getFalseValue() ==
SI.getTrueValue() ||
2481 Select->getTrueValue() ==
SI.getFalseValue())
2485 auto *CmpXchg = isExtractFromCmpXchg(
SI.getCondition(), 1);
2492 if (
auto *
X = isExtractFromCmpXchg(
SI.getTrueValue(), 0))
2493 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getFalseValue())
2494 return SI.getFalseValue();
2499 if (
auto *
X = isExtractFromCmpXchg(
SI.getFalseValue(), 0))
2500 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getTrueValue())
2501 return SI.getFalseValue();
2525 Value *SV0, *SV1, *SA0, *SA1;
2534 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2540 Or1->
getOpcode() == BinaryOperator::LShr &&
2541 "Illegal or(shift,shift) pair");
2556 bool IsFshl = (ShAmt == SA0);
2558 if ((IsFshl && TVal != SV0) || (!IsFshl && TVal != SV1))
2578 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
2600 assert(TC != FC &&
"Expected equal select arms to simplify");
2604 bool IsTrueIfSignSet;
2622 Value *MagArg = ConstantFP::get(SelType,
abs(*TC));
2629 if (!isa<VectorType>(Sel.
getType()))
2640 if (
auto *
I = dyn_cast<Instruction>(V))
2641 I->copyIRFlags(&Sel);
2644 M, Intrinsic::vector_reverse,
V->getType());
2652 return createSelReverse(
C,
X,
Y);
2656 return createSelReverse(
C,
X, FVal);
2661 return createSelReverse(
C, TVal,
Y);
2664 auto *VecTy = dyn_cast<FixedVectorType>(Sel.
getType());
2668 unsigned NumElts = VecTy->getNumElements();
2669 APInt PoisonElts(NumElts, 0);
2683 cast<ShuffleVectorInst>(TVal)->isSelect()) {
2697 cast<ShuffleVectorInst>(FVal)->isSelect()) {
2718 auto *IDomNode = DT[BB]->getIDom();
2724 Value *IfTrue, *IfFalse;
2740 if (TrueSucc == FalseSucc)
2761 if (
auto *
Insn = dyn_cast<Instruction>(Inputs[Pred]))
2780 if (
auto *
I = dyn_cast<Instruction>(V))
2781 CandidateBlocks.
insert(
I->getParent());
2784 if (
auto *PN = foldSelectToPhiImpl(Sel, BB, DT, Builder))
2797 Value *CondVal =
SI.getCondition();
2802 Value *
Op, *RemRes, *Remainder;
2804 bool TrueIfSigned =
false;
2818 return BinaryOperator::CreateAnd(
Op,
Add);
2830 return FoldToBitwiseAnd(Remainder);
2839 return FoldToBitwiseAnd(ConstantInt::get(RemRes->
getType(), 2));
2875 Value *InnerCondVal =
SI.getCondition();
2876 Value *InnerTrueVal =
SI.getTrueValue();
2877 Value *InnerFalseVal =
SI.getFalseValue();
2879 "The type of inner condition must match with the outer.");
2881 return *Implied ? InnerTrueVal : InnerFalseVal;
2888 assert(
Op->getType()->isIntOrIntVectorTy(1) &&
2889 "Op must be either i1 or vector of i1.");
2890 if (
SI.getCondition()->getType() !=
Op->getType())
2892 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(SI,
Op, IsAnd,
DL))
2903 Value *CondVal =
SI.getCondition();
2905 bool ChangedFMF =
false;
2906 for (
bool Swap : {
false,
true}) {
2936 FastMathFlags FMF = cast<FPMathOperator>(TrueVal)->getFastMathFlags();
2937 if (FMF.
noNaNs() && !
SI.hasNoNaNs()) {
2938 SI.setHasNoNaNs(
true);
2941 if (FMF.
noInfs() && !
SI.hasNoInfs()) {
2942 SI.setHasNoInfs(
true);
2956 if (!
SI.hasNoSignedZeros() || !
SI.hasNoNaNs())
2973 Instruction *NewFNeg = UnaryOperator::CreateFNeg(Fabs);
2982 for (
bool Swap : {
false,
true}) {
2998 if (Swap == TrueIfSigned && !CondVal->
hasOneUse() && !
TrueVal->hasOneUse())
3004 if (Swap != TrueIfSigned)
3009 return ChangedFMF ? &
SI :
nullptr;
3027foldRoundUpIntegerWithPow2Alignment(
SelectInst &SI,
3031 Value *XBiasedHighBits =
SI.getFalseValue();
3044 const APInt *LowBitMaskCst;
3049 const APInt *BiasCst, *HighBitMaskCst;
3050 if (!
match(XBiasedHighBits,
3053 !
match(XBiasedHighBits,
3058 if (!LowBitMaskCst->
isMask())
3061 APInt InvertedLowBitMaskCst = ~*LowBitMaskCst;
3062 if (InvertedLowBitMaskCst != *HighBitMaskCst)
3065 APInt AlignmentCst = *LowBitMaskCst + 1;
3067 if (*BiasCst != AlignmentCst && *BiasCst != *LowBitMaskCst)
3072 if (*BiasCst == *LowBitMaskCst &&
impliesPoison(XBiasedHighBits,
X))
3073 return XBiasedHighBits;
3078 Type *Ty =
X->getType();
3079 Value *XOffset = Builder.
CreateAdd(
X, ConstantInt::get(Ty, *LowBitMaskCst),
3080 X->getName() +
".biased");
3081 Value *
R = Builder.
CreateAnd(XOffset, ConstantInt::get(Ty, *HighBitMaskCst));
3087struct DecomposedSelect {
3099foldSelectOfSymmetricSelect(
SelectInst &OuterSelVal,
3102 Value *OuterCond, *InnerCond, *InnerTrueVal, *InnerFalseVal;
3130 DecomposedSelect OuterSel;
3137 std::swap(OuterSel.TrueVal, OuterSel.FalseVal);
3145 Value *InnerSelVal = IsAndVariant ? OuterSel.FalseVal : OuterSel.TrueVal;
3149 [](
Value *V) {
return V->hasOneUse(); }))
3153 DecomposedSelect InnerSel;
3154 if (!
match(InnerSelVal,
3161 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
3163 Value *AltCond =
nullptr;
3164 auto matchOuterCond = [OuterSel, IsAndVariant, &AltCond](
auto m_InnerCond) {
3169 return IsAndVariant ?
match(OuterSel.Cond,
3179 if (matchOuterCond(
m_Specific(InnerSel.Cond))) {
3184 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
3185 InnerSel.Cond = NotInnerCond;
3190 AltCond, IsAndVariant ? OuterSel.TrueVal : InnerSel.FalseVal,
3191 IsAndVariant ? InnerSel.TrueVal : OuterSel.FalseVal);
3194 IsAndVariant ? SelInner : InnerSel.TrueVal,
3195 !IsAndVariant ? SelInner : InnerSel.FalseVal);
3201static bool impliesPoisonOrCond(
const Value *ValAssumedPoison,
const Value *V,
3208 if (
auto *ICmp = dyn_cast<ICmpInst>(ValAssumedPoison)) {
3213 if (ICmp->hasSameSign() &&
3232 Value *CondVal =
SI.getCondition();
3235 Type *SelType =
SI.getType();
3252 if (impliesPoisonOrCond(FalseVal, CondVal,
false)) {
3254 return BinaryOperator::CreateOr(CondVal, FalseVal);
3258 impliesPoisonOrCond(FalseVal,
B,
false)) {
3268 bool CondLogicAnd = isa<SelectInst>(CondVal);
3269 bool FalseLogicAnd = isa<SelectInst>(FalseVal);
3270 auto AndFactorization = [&](
Value *Common,
Value *InnerCond,
3276 if (FalseLogicAnd || (CondLogicAnd && Common ==
A))
3279 return BinaryOperator::CreateAnd(Common, InnerSel);
3283 return AndFactorization(
A,
B,
D);
3285 return AndFactorization(
A,
B,
C);
3287 return AndFactorization(
B,
A,
D);
3289 return AndFactorization(
B,
A,
C, CondLogicAnd && FalseLogicAnd);
3294 if (impliesPoisonOrCond(TrueVal, CondVal,
true)) {
3296 return BinaryOperator::CreateAnd(CondVal, TrueVal);
3300 impliesPoisonOrCond(TrueVal,
B,
true)) {
3310 bool CondLogicOr = isa<SelectInst>(CondVal);
3311 bool TrueLogicOr = isa<SelectInst>(TrueVal);
3312 auto OrFactorization = [&](
Value *Common,
Value *InnerCond,
3318 if (TrueLogicOr || (CondLogicOr && Common ==
A))
3321 return BinaryOperator::CreateOr(Common, InnerSel);
3325 return OrFactorization(
A,
B,
D);
3327 return OrFactorization(
A,
B,
C);
3329 return OrFactorization(
B,
A,
D);
3331 return OrFactorization(
B,
A,
C, CondLogicOr && TrueLogicOr);
3374 return BinaryOperator::CreateXor(
A,
B);
3408 auto *FI =
new FreezeInst(*
Y, (*Y)->getName() +
".fr");
3414 if (
auto *V = foldBooleanAndOr(CondVal, Op1, SI, IsAnd,
3425 if (Res && *Res ==
false)
3431 if (Res && *Res ==
false)
3440 if (Res && *Res ==
true)
3446 if (Res && *Res ==
true)
3459 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3460 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3461 bool MayNeedFreeze = SelCond && SelFVal &&
3462 match(SelFVal->getTrueValue(),
3475 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3476 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3477 bool MayNeedFreeze = SelCond && SelFVal &&
3478 match(SelCond->getTrueValue(),
3494 bool &ShouldDropNUW) {
3517 ShouldDropNUW =
false;
3523 auto MatchForward = [&](
Value *CommonAncestor) {
3524 const APInt *
C =
nullptr;
3525 if (CtlzOp == CommonAncestor)
3532 ShouldDropNUW =
true;
3543 const APInt *
C =
nullptr;
3544 Value *CommonAncestor;
3545 if (MatchForward(Cond0)) {
3549 if (!MatchForward(CommonAncestor))
3587 Type *SelType =
SI.getType();
3594 Value *Cond0, *Ctlz, *CtlzOp;
3610 !isSafeToRemoveBitCeilSelect(Pred, Cond0, Cond1, CtlzOp,
BitWidth,
3615 cast<Instruction>(CtlzOp)->setHasNoUnsignedWrap(
false);
3623 cast<Instruction>(Ctlz)->dropPoisonGeneratingAnnotations();
3640 Value *TV =
SI.getTrueValue();
3641 Value *FV =
SI.getFalseValue();
3662 bool Replace =
false;
3684 const APInt *InnerTV, *InnerFV;
3690 FalseBranchSelectPredicate =
3695 if (!InnerTV->
isOne()) {
3707 Intrinsic::ID IID = IsSigned ? Intrinsic::scmp : Intrinsic::ucmp;
3729 FastMathFlags FMF = cast<FPMathOperator>(TrueVal)->getFastMathFlags();
3751 if (
auto *
I = dyn_cast<Instruction>(V)) {
3752 if (isa<PHINode>(
I)) {
3758 return Op->getType()->isIntOrIntVectorTy() &&
3759 hasAffectedValue(Op, Affected, Depth + 1);
3772 auto *SIFOp = dyn_cast<FPMathOperator>(&SI);
3773 if (!SIFOp || !SIFOp->hasNoSignedZeros() || !SIFOp->hasNoNaNs())
3776 auto TryFoldIntoAddConstant =
3788 Swapped ?
X :
Z,
"", &
SI);
3799 cast<Instruction>(NewFAdd)->setFastMathFlags(NewFMF);
3800 cast<Instruction>(NewSelect)->setFastMathFlags(NewFMF);
3819 return TryFoldIntoAddConstant(Pred,
X, Z,
FAdd,
C,
false);
3823 return TryFoldIntoAddConstant(Pred,
X, Z,
FAdd,
C,
true);
3829 Value *CondVal =
SI.getCondition();
3832 Type *SelType =
SI.getType();
3841 if (
Instruction *
I = canonicalizeScalarSelectOfVecs(SI, *
this))
3883 return new ZExtInst(CondVal, SelType);
3887 return new SExtInst(CondVal, SelType);
3892 return new ZExtInst(NotCond, SelType);
3898 return new SExtInst(NotCond, SelType);
3902 auto *SIFPOp = dyn_cast<FPMathOperator>(&SI);
3904 if (
auto *FCmp = dyn_cast<FCmpInst>(CondVal)) {
3906 Value *Cmp0 = FCmp->getOperand(0), *Cmp1 = FCmp->getOperand(1);
3908 if ((Cmp0 == TrueVal && Cmp1 == FalseVal) ||
3909 (Cmp0 == FalseVal && Cmp1 == TrueVal)) {
3919 FCmp->getName() +
".inv");
3940 Value *MatchCmp0 =
nullptr;
3941 Value *MatchCmp1 =
nullptr;
3953 if (Cmp0 == MatchCmp0 &&
3954 matchFMulByZeroIfResultEqZero(*
this, Cmp0, Cmp1, MatchCmp1, MatchCmp0,
3955 SI, SIFPOp->hasNoSignedZeros()))
3963 auto *FCmp = dyn_cast<FCmpInst>(CondVal);
3967 if (SIFPOp->hasNoNaNs() && SIFPOp->hasNoSignedZeros()) {
3972 if (
auto *BinIntrInst = dyn_cast<Instruction>(BinIntr))
3973 BinIntrInst->setHasNoNaNs(FCmp->hasNoNaNs());
3980 if (
auto *BinIntrInst = dyn_cast<Instruction>(BinIntr))
3981 BinIntrInst->setHasNoNaNs(FCmp->hasNoNaNs());
3988 if (
Instruction *Fabs = foldSelectWithFCmpToFabs(SI, *
this))
3992 if (
CmpInst *CI = dyn_cast<CmpInst>(CondVal))
3996 if (
ICmpInst *ICI = dyn_cast<ICmpInst>(CondVal))
4010 auto *TI = dyn_cast<Instruction>(TrueVal);
4011 auto *FI = dyn_cast<Instruction>(FalseVal);
4012 if (TI && FI && TI->getOpcode() == FI->
getOpcode())
4031 if (isa<VectorType>(CondVal->
getType()) && !isa<VectorType>(
Idx->getType()))
4043 if (
auto *TrueGep = dyn_cast<GetElementPtrInst>(TrueVal))
4044 if (
auto *NewGep = SelectGepWithBase(TrueGep, FalseVal,
false))
4046 if (
auto *FalseGep = dyn_cast<GetElementPtrInst>(FalseVal))
4047 if (
auto *NewGep = SelectGepWithBase(FalseGep, TrueVal,
true))
4063 RHS2, SI, SPF, RHS))
4067 RHS2, SI, SPF, LHS))
4076 bool IsCastNeeded =
LHS->
getType() != SelType;
4077 Value *CmpLHS = cast<CmpInst>(CondVal)->getOperand(0);
4078 Value *CmpRHS = cast<CmpInst>(CondVal)->getOperand(1);
4081 ((CmpLHS != LHS && CmpLHS != RHS) ||
4082 (CmpRHS != LHS && CmpRHS != RHS)))) {
4090 cast<Instruction>(
SI.getCondition()));
4103 if (
auto *PN = dyn_cast<PHINode>(
SI.getCondition()))
4107 if (
SelectInst *TrueSI = dyn_cast<SelectInst>(TrueVal)) {
4108 if (TrueSI->getCondition()->getType() == CondVal->
getType()) {
4111 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(
4112 *TrueSI, CondVal,
true,
DL))
4119 if (TrueSI->getFalseValue() == FalseVal && TrueSI->hasOneUse()) {
4127 if (
SelectInst *FalseSI = dyn_cast<SelectInst>(FalseVal)) {
4128 if (FalseSI->getCondition()->getType() == CondVal->
getType()) {
4131 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(
4132 *FalseSI, CondVal,
false,
DL))
4136 if (FalseSI->getTrueValue() == TrueVal && FalseSI->hasOneUse()) {
4153 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(0))) {
4154 if (TrueBOSI->getCondition() == CondVal) {
4160 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(1))) {
4161 if (TrueBOSI->getCondition() == CondVal) {
4172 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(0))) {
4173 if (FalseBOSI->getCondition() == CondVal) {
4179 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(1))) {
4180 if (FalseBOSI->getCondition() == CondVal) {
4193 SI.swapProfMetadata();
4208 if (Known.One.isOne())
4210 if (Known.Zero.isOne())
4218 if (
Value *V = foldSelectCmpXchg(SI))
4236 if (
Value *V = foldRoundUpIntegerWithPow2Alignment(SI,
Builder))
4249 auto *MaskedInst = cast<IntrinsicInst>(TrueVal);
4250 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
4251 MaskedInst->setArgOperand(3, FalseVal );