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();
1238 if (!
TrueVal->getType()->isIntOrIntVectorTy())
1275 assert(!isa<Constant>(Old) &&
"Only replace non-constant values");
1277 auto *
I = dyn_cast<Instruction>(V);
1278 if (!
I || !
I->hasOneUse() ||
1286 bool Changed =
false;
1287 for (
Use &U :
I->operands()) {
1320 bool Swapped =
false;
1321 if (
Cmp.isEquivalence(
true)) {
1324 }
else if (!
Cmp.isEquivalence()) {
1328 Value *CmpLHS =
Cmp.getOperand(0), *CmpRHS =
Cmp.getOperand(1);
1329 auto ReplaceOldOpWithNewOp = [&](
Value *OldOp,
1337 if (TrueVal == OldOp && (isa<Constant>(OldOp) || !isa<Constant>(NewOp)))
1372 if (
Instruction *R = ReplaceOldOpWithNewOp(CmpLHS, CmpRHS))
1374 if (
Instruction *R = ReplaceOldOpWithNewOp(CmpRHS, CmpLHS))
1377 auto *FalseInst = dyn_cast<Instruction>(FalseVal);
1392 &DropFlags) == TrueVal ||
1395 &DropFlags) == TrueVal) {
1397 I->dropPoisonGeneratingAnnotations();
1442 cast<ICmpInst>(XeqY)->setSameSign(
false);
1477 if (!isa<SelectInst>(Sel1)) {
1518 if (Cmp00->
getType() !=
X->getType() &&
X->hasOneUse())
1526 else if (!
match(Cmp00,
1534 Value *ReplacementLow, *ReplacementHigh;
1571 std::swap(ReplacementLow, ReplacementHigh);
1577 "Unexpected predicate type.");
1585 "Unexpected predicate type.");
1587 std::swap(ThresholdLowIncl, ThresholdHighExcl);
1603 if (
X->getType() != Sel0.
getType()) {
1613 assert(ReplacementLow && ReplacementHigh &&
1614 "Constant folding of ImmConstant cannot fail");
1620 Value *MaybeReplacedLow =
1626 ShouldReplaceHigh, ReplacementHigh, MaybeReplacedLow);
1670 Value *SelVal0, *SelVal1;
1679 auto MatchesSelectValue = [SelVal0, SelVal1](
Constant *
C) {
1680 return C->isElementWiseEqual(SelVal0) ||
C->isElementWiseEqual(SelVal1);
1684 if (MatchesSelectValue(C0))
1688 auto FlippedStrictness =
1690 if (!FlippedStrictness)
1694 if (!MatchesSelectValue(FlippedStrictness->second))
1703 Cmp.getName() +
".inv");
1714 if (!
Cmp->hasOneUse())
1744 Value *TVal =
SI.getTrueValue();
1745 Value *FVal =
SI.getFalseValue();
1771 const APInt *BinOpC;
1839 foldSelectWithExtremeEqCond(CmpLHS, CmpRHS, TrueVal, FalseVal))
1852 const unsigned AndOps = Instruction::And, OrOps = Instruction::Or,
1853 XorOps = Instruction::Xor, NoOps = 0;
1854 enum NotMask {
None = 0, NotInner, NotRHS };
1856 auto matchFalseVal = [&](
unsigned OuterOpc,
unsigned InnerOpc,
1859 if (OuterOpc == NoOps)
1862 if (NotMask == NotInner) {
1865 }
else if (NotMask == NotRHS) {
1869 return match(FalseVal,
1880 if (matchFalseVal(OrOps, XorOps,
None) ||
1881 matchFalseVal(XorOps, XorOps,
None))
1886 if (matchFalseVal(XorOps, OrOps,
None) ||
1887 matchFalseVal(AndOps, OrOps, NotRHS))
1898 if (matchFalseVal(XorOps, XorOps,
None) ||
1899 matchFalseVal(AndOps, XorOps, NotInner))
1904 if (matchFalseVal(XorOps, AndOps,
None) ||
1905 matchFalseVal(AndOps, AndOps, NotInner))
1916 if (matchFalseVal(XorOps, OrOps,
None) ||
1917 matchFalseVal(AndOps, OrOps, NotRHS))
1922 if (matchFalseVal(OrOps, AndOps,
None) ||
1923 matchFalseVal(XorOps, AndOps,
None))
1976 Opcode, Flipped->second, C2,
DL)) {
1978 RHS = Flipped->second;
1992 canonicalizeSPF(*ICI,
SI.getTrueValue(),
SI.getFalseValue(), *
this))
1995 if (
Value *V = foldSelectInstWithICmpConst(SI, ICI,
Builder))
1998 if (
Value *V = canonicalizeClampLike(SI, *ICI,
Builder, *
this))
2002 tryToReuseConstantFromSelectInComparison(SI, *ICI, *
this))
2009 bool Changed =
false;
2016 if (
Instruction *NewSel = foldSelectICmpEq(SI, ICI, *
this))
2031 SI.swapProfMetadata();
2054 if (
Value *V = foldSelectCttzCtlz(ICI, TrueVal, FalseVal, *
this))
2066 if (
Value *V = foldSelectWithConstOpToBinOp(ICI, TrueVal, FalseVal,
Builder))
2069 return Changed ? &
SI :
nullptr;
2082 if (
C ==
A ||
C ==
B) {
2097 Value *CondVal =
SI.getCondition();
2100 auto *TI = dyn_cast<Instruction>(TrueVal);
2101 auto *FI = dyn_cast<Instruction>(FalseVal);
2102 if (!TI || !FI || !TI->hasOneUse() || !FI->hasOneUse())
2106 if ((TI->getOpcode() == Instruction::Sub &&
2107 FI->getOpcode() == Instruction::Add) ||
2108 (TI->getOpcode() == Instruction::FSub &&
2109 FI->getOpcode() == Instruction::FAdd)) {
2112 }
else if ((FI->getOpcode() == Instruction::Sub &&
2113 TI->getOpcode() == Instruction::Add) ||
2114 (FI->getOpcode() == Instruction::FSub &&
2115 TI->getOpcode() == Instruction::FAdd)) {
2121 Value *OtherAddOp =
nullptr;
2122 if (SubOp->getOperand(0) == AddOp->
getOperand(0)) {
2124 }
else if (SubOp->getOperand(0) == AddOp->
getOperand(1)) {
2132 if (
SI.getType()->isFPOrFPVectorTy()) {
2133 NegVal = Builder.
CreateFNeg(SubOp->getOperand(1));
2134 if (
Instruction *NegInst = dyn_cast<Instruction>(NegVal)) {
2136 Flags &= SubOp->getFastMathFlags();
2137 NegInst->setFastMathFlags(Flags);
2140 NegVal = Builder.
CreateNeg(SubOp->getOperand(1));
2143 Value *NewTrueOp = OtherAddOp;
2144 Value *NewFalseOp = NegVal;
2148 SI.getName() +
".p", &SI);
2150 if (
SI.getType()->isFPOrFPVectorTy()) {
2152 BinaryOperator::CreateFAdd(SubOp->getOperand(0), NewSel);
2155 Flags &= SubOp->getFastMathFlags();
2159 return BinaryOperator::CreateAdd(SubOp->getOperand(0), NewSel);
2172 Value *CondVal =
SI.getCondition();
2184 auto IsSignedSaturateLimit = [&](
Value *Limit,
bool IsAdd) {
2194 auto IsZeroOrOne = [](
const APInt &
C) {
return C.isZero() ||
C.isOne(); };
2211 IsMinMax(TrueVal, FalseVal))
2218 IsMinMax(FalseVal, TrueVal))
2224 IsMinMax(TrueVal, FalseVal))
2229 IsMinMax(FalseVal, TrueVal))
2234 IsMinMax(FalseVal, TrueVal))
2239 IsMinMax(TrueVal, FalseVal))
2247 if (
II->getIntrinsicID() == Intrinsic::uadd_with_overflow &&
2250 NewIntrinsicID = Intrinsic::uadd_sat;
2251 else if (
II->getIntrinsicID() == Intrinsic::usub_with_overflow &&
2254 NewIntrinsicID = Intrinsic::usub_sat;
2255 else if (
II->getIntrinsicID() == Intrinsic::sadd_with_overflow &&
2256 IsSignedSaturateLimit(TrueVal,
true))
2265 NewIntrinsicID = Intrinsic::sadd_sat;
2266 else if (
II->getIntrinsicID() == Intrinsic::ssub_with_overflow &&
2267 IsSignedSaturateLimit(TrueVal,
false))
2276 NewIntrinsicID = Intrinsic::ssub_sat;
2281 NewIntrinsicID,
SI.getType());
2297 if (ExtOpcode != Instruction::ZExt && ExtOpcode != Instruction::SExt)
2303 Type *SmallType =
X->getType();
2305 auto *
Cmp = dyn_cast<CmpInst>(
Cond);
2307 (!Cmp ||
Cmp->getOperand(0)->getType() != SmallType))
2315 Value *TruncCVal = cast<Value>(TruncC);
2331 Value *CondVal =
SI.getCondition();
2333 auto *CondValTy = dyn_cast<FixedVectorType>(CondVal->
getType());
2337 unsigned NumElts = CondValTy->getNumElements();
2339 Mask.reserve(NumElts);
2340 for (
unsigned i = 0; i != NumElts; ++i) {
2350 Mask.push_back(i + NumElts);
2351 }
else if (isa<UndefValue>(Elt)) {
2371 auto *Ty = dyn_cast<VectorType>(Sel.
getType());
2403 if (TVal ==
A || TVal ==
B || FVal ==
A || FVal ==
B)
2420 if (TSrc ==
C && FSrc ==
D) {
2424 }
else if (TSrc ==
D && FSrc ==
C) {
2463 auto *Extract = dyn_cast<ExtractValueInst>(V);
2466 if (Extract->getIndices()[0] !=
I)
2468 return dyn_cast<AtomicCmpXchgInst>(Extract->getAggregateOperand());
2474 if (
auto *
Select = dyn_cast<SelectInst>(
SI.user_back()))
2475 if (
Select->getCondition() ==
SI.getCondition())
2476 if (
Select->getFalseValue() ==
SI.getTrueValue() ||
2477 Select->getTrueValue() ==
SI.getFalseValue())
2481 auto *CmpXchg = isExtractFromCmpXchg(
SI.getCondition(), 1);
2488 if (
auto *
X = isExtractFromCmpXchg(
SI.getTrueValue(), 0))
2489 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getFalseValue())
2490 return SI.getFalseValue();
2495 if (
auto *
X = isExtractFromCmpXchg(
SI.getFalseValue(), 0))
2496 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getTrueValue())
2497 return SI.getFalseValue();
2521 Value *SV0, *SV1, *SA0, *SA1;
2530 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2536 Or1->
getOpcode() == BinaryOperator::LShr &&
2537 "Illegal or(shift,shift) pair");
2552 bool IsFshl = (ShAmt == SA0);
2554 if ((IsFshl && TVal != SV0) || (!IsFshl && TVal != SV1))
2574 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
2596 assert(TC != FC &&
"Expected equal select arms to simplify");
2600 bool IsTrueIfSignSet;
2618 Value *MagArg = ConstantFP::get(SelType,
abs(*TC));
2625 if (!isa<VectorType>(Sel.
getType()))
2636 if (
auto *
I = dyn_cast<Instruction>(V))
2637 I->copyIRFlags(&Sel);
2640 M, Intrinsic::vector_reverse,
V->getType());
2648 return createSelReverse(
C,
X,
Y);
2652 return createSelReverse(
C,
X, FVal);
2657 return createSelReverse(
C, TVal,
Y);
2660 auto *VecTy = dyn_cast<FixedVectorType>(Sel.
getType());
2664 unsigned NumElts = VecTy->getNumElements();
2665 APInt PoisonElts(NumElts, 0);
2679 cast<ShuffleVectorInst>(TVal)->isSelect()) {
2693 cast<ShuffleVectorInst>(FVal)->isSelect()) {
2714 auto *IDomNode = DT[BB]->getIDom();
2720 Value *IfTrue, *IfFalse;
2736 if (TrueSucc == FalseSucc)
2757 if (
auto *
Insn = dyn_cast<Instruction>(Inputs[Pred]))
2776 if (
auto *
I = dyn_cast<Instruction>(V))
2777 CandidateBlocks.
insert(
I->getParent());
2780 if (
auto *PN = foldSelectToPhiImpl(Sel, BB, DT, Builder))
2793 Value *CondVal =
SI.getCondition();
2798 Value *
Op, *RemRes, *Remainder;
2800 bool TrueIfSigned =
false;
2814 return BinaryOperator::CreateAnd(
Op,
Add);
2826 return FoldToBitwiseAnd(Remainder);
2835 return FoldToBitwiseAnd(ConstantInt::get(RemRes->
getType(), 2));
2871 Value *InnerCondVal =
SI.getCondition();
2872 Value *InnerTrueVal =
SI.getTrueValue();
2873 Value *InnerFalseVal =
SI.getFalseValue();
2875 "The type of inner condition must match with the outer.");
2877 return *Implied ? InnerTrueVal : InnerFalseVal;
2884 assert(
Op->getType()->isIntOrIntVectorTy(1) &&
2885 "Op must be either i1 or vector of i1.");
2886 if (
SI.getCondition()->getType() !=
Op->getType())
2888 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(SI,
Op, IsAnd,
DL))
2899 Value *CondVal =
SI.getCondition();
2901 bool ChangedFMF =
false;
2902 for (
bool Swap : {
false,
true}) {
2932 FastMathFlags FMF = cast<FPMathOperator>(TrueVal)->getFastMathFlags();
2933 if (FMF.
noNaNs() && !
SI.hasNoNaNs()) {
2934 SI.setHasNoNaNs(
true);
2937 if (FMF.
noInfs() && !
SI.hasNoInfs()) {
2938 SI.setHasNoInfs(
true);
2952 if (!
SI.hasNoSignedZeros() || !
SI.hasNoNaNs())
2969 Instruction *NewFNeg = UnaryOperator::CreateFNeg(Fabs);
2978 for (
bool Swap : {
false,
true}) {
2994 if (Swap == TrueIfSigned && !CondVal->
hasOneUse() && !
TrueVal->hasOneUse())
3000 if (Swap != TrueIfSigned)
3005 return ChangedFMF ? &
SI :
nullptr;
3023foldRoundUpIntegerWithPow2Alignment(
SelectInst &SI,
3027 Value *XBiasedHighBits =
SI.getFalseValue();
3040 const APInt *LowBitMaskCst;
3045 const APInt *BiasCst, *HighBitMaskCst;
3046 if (!
match(XBiasedHighBits,
3049 !
match(XBiasedHighBits,
3054 if (!LowBitMaskCst->
isMask())
3057 APInt InvertedLowBitMaskCst = ~*LowBitMaskCst;
3058 if (InvertedLowBitMaskCst != *HighBitMaskCst)
3061 APInt AlignmentCst = *LowBitMaskCst + 1;
3063 if (*BiasCst != AlignmentCst && *BiasCst != *LowBitMaskCst)
3068 if (*BiasCst == *LowBitMaskCst &&
impliesPoison(XBiasedHighBits,
X))
3069 return XBiasedHighBits;
3074 Type *Ty =
X->getType();
3075 Value *XOffset = Builder.
CreateAdd(
X, ConstantInt::get(Ty, *LowBitMaskCst),
3076 X->getName() +
".biased");
3077 Value *
R = Builder.
CreateAnd(XOffset, ConstantInt::get(Ty, *HighBitMaskCst));
3083struct DecomposedSelect {
3095foldSelectOfSymmetricSelect(
SelectInst &OuterSelVal,
3098 Value *OuterCond, *InnerCond, *InnerTrueVal, *InnerFalseVal;
3126 DecomposedSelect OuterSel;
3133 std::swap(OuterSel.TrueVal, OuterSel.FalseVal);
3141 Value *InnerSelVal = IsAndVariant ? OuterSel.FalseVal : OuterSel.TrueVal;
3145 [](
Value *V) {
return V->hasOneUse(); }))
3149 DecomposedSelect InnerSel;
3150 if (!
match(InnerSelVal,
3157 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
3159 Value *AltCond =
nullptr;
3160 auto matchOuterCond = [OuterSel, IsAndVariant, &AltCond](
auto m_InnerCond) {
3165 return IsAndVariant ?
match(OuterSel.Cond,
3175 if (matchOuterCond(
m_Specific(InnerSel.Cond))) {
3180 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
3181 InnerSel.Cond = NotInnerCond;
3186 AltCond, IsAndVariant ? OuterSel.TrueVal : InnerSel.FalseVal,
3187 IsAndVariant ? InnerSel.TrueVal : OuterSel.FalseVal);
3190 IsAndVariant ? SelInner : InnerSel.TrueVal,
3191 !IsAndVariant ? SelInner : InnerSel.FalseVal);
3197static bool impliesPoisonOrCond(
const Value *ValAssumedPoison,
const Value *V,
3204 if (
auto *ICmp = dyn_cast<ICmpInst>(ValAssumedPoison)) {
3209 if (ICmp->hasSameSign() &&
3228 Value *CondVal =
SI.getCondition();
3231 Type *SelType =
SI.getType();
3248 if (impliesPoisonOrCond(FalseVal, CondVal,
false)) {
3250 return BinaryOperator::CreateOr(CondVal, FalseVal);
3254 impliesPoisonOrCond(FalseVal,
B,
false)) {
3264 bool CondLogicAnd = isa<SelectInst>(CondVal);
3265 bool FalseLogicAnd = isa<SelectInst>(FalseVal);
3266 auto AndFactorization = [&](
Value *Common,
Value *InnerCond,
3272 if (FalseLogicAnd || (CondLogicAnd && Common ==
A))
3275 return BinaryOperator::CreateAnd(Common, InnerSel);
3279 return AndFactorization(
A,
B,
D);
3281 return AndFactorization(
A,
B,
C);
3283 return AndFactorization(
B,
A,
D);
3285 return AndFactorization(
B,
A,
C, CondLogicAnd && FalseLogicAnd);
3290 if (impliesPoisonOrCond(TrueVal, CondVal,
true)) {
3292 return BinaryOperator::CreateAnd(CondVal, TrueVal);
3296 impliesPoisonOrCond(TrueVal,
B,
true)) {
3306 bool CondLogicOr = isa<SelectInst>(CondVal);
3307 bool TrueLogicOr = isa<SelectInst>(TrueVal);
3308 auto OrFactorization = [&](
Value *Common,
Value *InnerCond,
3314 if (TrueLogicOr || (CondLogicOr && Common ==
A))
3317 return BinaryOperator::CreateOr(Common, InnerSel);
3321 return OrFactorization(
A,
B,
D);
3323 return OrFactorization(
A,
B,
C);
3325 return OrFactorization(
B,
A,
D);
3327 return OrFactorization(
B,
A,
C, CondLogicOr && TrueLogicOr);
3370 return BinaryOperator::CreateXor(
A,
B);
3404 auto *FI =
new FreezeInst(*
Y, (*Y)->getName() +
".fr");
3410 if (
auto *V = foldBooleanAndOr(CondVal, Op1, SI, IsAnd,
3421 if (Res && *Res ==
false)
3427 if (Res && *Res ==
false)
3436 if (Res && *Res ==
true)
3442 if (Res && *Res ==
true)
3455 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3456 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3457 bool MayNeedFreeze = SelCond && SelFVal &&
3458 match(SelFVal->getTrueValue(),
3471 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3472 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3473 bool MayNeedFreeze = SelCond && SelFVal &&
3474 match(SelCond->getTrueValue(),
3490 bool &ShouldDropNUW) {
3513 ShouldDropNUW =
false;
3519 auto MatchForward = [&](
Value *CommonAncestor) {
3520 const APInt *
C =
nullptr;
3521 if (CtlzOp == CommonAncestor)
3528 ShouldDropNUW =
true;
3539 const APInt *
C =
nullptr;
3540 Value *CommonAncestor;
3541 if (MatchForward(Cond0)) {
3545 if (!MatchForward(CommonAncestor))
3583 Type *SelType =
SI.getType();
3590 Value *Cond0, *Ctlz, *CtlzOp;
3606 !isSafeToRemoveBitCeilSelect(Pred, Cond0, Cond1, CtlzOp,
BitWidth,
3611 cast<Instruction>(CtlzOp)->setHasNoUnsignedWrap(
false);
3619 cast<Instruction>(Ctlz)->dropPoisonGeneratingAnnotations();
3636 Value *TV =
SI.getTrueValue();
3637 Value *FV =
SI.getFalseValue();
3658 bool Replace =
false;
3680 const APInt *InnerTV, *InnerFV;
3686 FalseBranchSelectPredicate =
3691 if (!InnerTV->
isOne()) {
3703 Intrinsic::ID IID = IsSigned ? Intrinsic::scmp : Intrinsic::ucmp;
3725 FastMathFlags FMF = cast<FPMathOperator>(TrueVal)->getFastMathFlags();
3747 if (
auto *
I = dyn_cast<Instruction>(V)) {
3748 if (isa<PHINode>(
I)) {
3754 return Op->getType()->isIntOrIntVectorTy() &&
3755 hasAffectedValue(Op, Affected, Depth + 1);
3768 auto *SIFOp = dyn_cast<FPMathOperator>(&SI);
3769 if (!SIFOp || !SIFOp->hasNoSignedZeros() || !SIFOp->hasNoNaNs())
3772 auto TryFoldIntoAddConstant =
3784 Swapped ?
X :
Z,
"", &
SI);
3795 cast<Instruction>(NewFAdd)->setFastMathFlags(NewFMF);
3796 cast<Instruction>(NewSelect)->setFastMathFlags(NewFMF);
3815 return TryFoldIntoAddConstant(Pred,
X, Z,
FAdd,
C,
false);
3819 return TryFoldIntoAddConstant(Pred,
X, Z,
FAdd,
C,
true);
3825 Value *CondVal =
SI.getCondition();
3828 Type *SelType =
SI.getType();
3837 if (
Instruction *
I = canonicalizeScalarSelectOfVecs(SI, *
this))
3879 return new ZExtInst(CondVal, SelType);
3883 return new SExtInst(CondVal, SelType);
3888 return new ZExtInst(NotCond, SelType);
3894 return new SExtInst(NotCond, SelType);
3898 auto *SIFPOp = dyn_cast<FPMathOperator>(&SI);
3900 if (
auto *FCmp = dyn_cast<FCmpInst>(CondVal)) {
3902 Value *Cmp0 = FCmp->getOperand(0), *Cmp1 = FCmp->getOperand(1);
3904 if ((Cmp0 == TrueVal && Cmp1 == FalseVal) ||
3905 (Cmp0 == FalseVal && Cmp1 == TrueVal)) {
3917 FCmp->getName() +
".inv");
3937 Value *MatchCmp0 =
nullptr;
3938 Value *MatchCmp1 =
nullptr;
3950 if (Cmp0 == MatchCmp0 &&
3951 matchFMulByZeroIfResultEqZero(*
this, Cmp0, Cmp1, MatchCmp1, MatchCmp0,
3952 SI, SIFPOp->hasNoSignedZeros()))
3960 auto *FCmp = dyn_cast<FCmpInst>(CondVal);
3964 if (SIFPOp->hasNoNaNs() && SIFPOp->hasNoSignedZeros()) {
3969 if (
auto *BinIntrInst = dyn_cast<Instruction>(BinIntr))
3970 BinIntrInst->setHasNoNaNs(FCmp->hasNoNaNs());
3977 if (
auto *BinIntrInst = dyn_cast<Instruction>(BinIntr))
3978 BinIntrInst->setHasNoNaNs(FCmp->hasNoNaNs());
3985 if (
Instruction *Fabs = foldSelectWithFCmpToFabs(SI, *
this))
3989 if (
CmpInst *CI = dyn_cast<CmpInst>(CondVal))
3993 if (
ICmpInst *ICI = dyn_cast<ICmpInst>(CondVal))
4007 auto *TI = dyn_cast<Instruction>(TrueVal);
4008 auto *FI = dyn_cast<Instruction>(FalseVal);
4009 if (TI && FI && TI->getOpcode() == FI->
getOpcode())
4028 if (isa<VectorType>(CondVal->
getType()) && !isa<VectorType>(
Idx->getType()))
4040 if (
auto *TrueGep = dyn_cast<GetElementPtrInst>(TrueVal))
4041 if (
auto *NewGep = SelectGepWithBase(TrueGep, FalseVal,
false))
4043 if (
auto *FalseGep = dyn_cast<GetElementPtrInst>(FalseVal))
4044 if (
auto *NewGep = SelectGepWithBase(FalseGep, TrueVal,
true))
4060 RHS2, SI, SPF, RHS))
4064 RHS2, SI, SPF, LHS))
4073 bool IsCastNeeded =
LHS->
getType() != SelType;
4074 Value *CmpLHS = cast<CmpInst>(CondVal)->getOperand(0);
4075 Value *CmpRHS = cast<CmpInst>(CondVal)->getOperand(1);
4078 ((CmpLHS != LHS && CmpLHS != RHS) ||
4079 (CmpRHS != LHS && CmpRHS != RHS)))) {
4088 cast<FPMathOperator>(
SI.getCondition())->getFastMathFlags();
4104 if (
auto *PN = dyn_cast<PHINode>(
SI.getCondition()))
4108 if (
SelectInst *TrueSI = dyn_cast<SelectInst>(TrueVal)) {
4109 if (TrueSI->getCondition()->getType() == CondVal->
getType()) {
4112 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(
4113 *TrueSI, CondVal,
true,
DL))
4120 if (TrueSI->getFalseValue() == FalseVal && TrueSI->hasOneUse()) {
4128 if (
SelectInst *FalseSI = dyn_cast<SelectInst>(FalseVal)) {
4129 if (FalseSI->getCondition()->getType() == CondVal->
getType()) {
4132 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(
4133 *FalseSI, CondVal,
false,
DL))
4137 if (FalseSI->getTrueValue() == TrueVal && FalseSI->hasOneUse()) {
4154 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(0))) {
4155 if (TrueBOSI->getCondition() == CondVal) {
4161 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(1))) {
4162 if (TrueBOSI->getCondition() == CondVal) {
4173 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(0))) {
4174 if (FalseBOSI->getCondition() == CondVal) {
4180 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(1))) {
4181 if (FalseBOSI->getCondition() == CondVal) {
4194 SI.swapProfMetadata();
4209 if (Known.One.isOne())
4211 if (Known.Zero.isOne())
4219 if (
Value *V = foldSelectCmpXchg(SI))
4237 if (
Value *V = foldRoundUpIntegerWithPow2Alignment(SI,
Builder))
4250 auto *MaskedInst = cast<IntrinsicInst>(TrueVal);
4251 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
4252 MaskedInst->setArgOperand(3, FalseVal );