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())
3807 cast<Instruction>(NewFAdd)->setFastMathFlags(NewFMF);
3808 cast<Instruction>(NewSelect)->setFastMathFlags(NewFMF);
3817 Value *CondVal =
SI.getCondition();
3820 Type *SelType =
SI.getType();
3829 if (
Instruction *
I = canonicalizeScalarSelectOfVecs(SI, *
this))
3871 return new ZExtInst(CondVal, SelType);
3875 return new SExtInst(CondVal, SelType);
3880 return new ZExtInst(NotCond, SelType);
3886 return new SExtInst(NotCond, SelType);
3890 auto *SIFPOp = dyn_cast<FPMathOperator>(&SI);
3892 if (
auto *FCmp = dyn_cast<FCmpInst>(CondVal)) {
3894 Value *Cmp0 = FCmp->getOperand(0), *Cmp1 = FCmp->getOperand(1);
3896 if ((Cmp0 == TrueVal && Cmp1 == FalseVal) ||
3897 (Cmp0 == FalseVal && Cmp1 == TrueVal)) {
3909 FCmp->getName() +
".inv");
3929 Value *MatchCmp0 =
nullptr;
3930 Value *MatchCmp1 =
nullptr;
3942 if (Cmp0 == MatchCmp0 &&
3943 matchFMulByZeroIfResultEqZero(*
this, Cmp0, Cmp1, MatchCmp1, MatchCmp0,
3944 SI, SIFPOp->hasNoSignedZeros()))
3952 auto *FCmp = dyn_cast<FCmpInst>(CondVal);
3956 if (SIFPOp->hasNoNaNs() && SIFPOp->hasNoSignedZeros()) {
3961 if (
auto *BinIntrInst = dyn_cast<Instruction>(BinIntr))
3962 BinIntrInst->setHasNoNaNs(FCmp->hasNoNaNs());
3969 if (
auto *BinIntrInst = dyn_cast<Instruction>(BinIntr))
3970 BinIntrInst->setHasNoNaNs(FCmp->hasNoNaNs());
3977 if (
Instruction *Fabs = foldSelectWithFCmpToFabs(SI, *
this))
3981 if (
CmpInst *CI = dyn_cast<CmpInst>(CondVal))
3985 if (
ICmpInst *ICI = dyn_cast<ICmpInst>(CondVal))
3999 auto *TI = dyn_cast<Instruction>(TrueVal);
4000 auto *FI = dyn_cast<Instruction>(FalseVal);
4001 if (TI && FI && TI->getOpcode() == FI->
getOpcode())
4020 if (isa<VectorType>(CondVal->
getType()) && !isa<VectorType>(
Idx->getType()))
4032 if (
auto *TrueGep = dyn_cast<GetElementPtrInst>(TrueVal))
4033 if (
auto *NewGep = SelectGepWithBase(TrueGep, FalseVal,
false))
4035 if (
auto *FalseGep = dyn_cast<GetElementPtrInst>(FalseVal))
4036 if (
auto *NewGep = SelectGepWithBase(FalseGep, TrueVal,
true))
4052 RHS2, SI, SPF, RHS))
4056 RHS2, SI, SPF, LHS))
4065 bool IsCastNeeded =
LHS->
getType() != SelType;
4066 Value *CmpLHS = cast<CmpInst>(CondVal)->getOperand(0);
4067 Value *CmpRHS = cast<CmpInst>(CondVal)->getOperand(1);
4070 ((CmpLHS != LHS && CmpLHS != RHS) ||
4071 (CmpRHS != LHS && CmpRHS != RHS)))) {
4080 cast<FPMathOperator>(
SI.getCondition())->getFastMathFlags();
4096 if (
auto *PN = dyn_cast<PHINode>(
SI.getCondition()))
4100 if (
SelectInst *TrueSI = dyn_cast<SelectInst>(TrueVal)) {
4101 if (TrueSI->getCondition()->getType() == CondVal->
getType()) {
4104 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(
4105 *TrueSI, CondVal,
true,
DL))
4112 if (TrueSI->getFalseValue() == FalseVal && TrueSI->hasOneUse()) {
4120 if (
SelectInst *FalseSI = dyn_cast<SelectInst>(FalseVal)) {
4121 if (FalseSI->getCondition()->getType() == CondVal->
getType()) {
4124 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(
4125 *FalseSI, CondVal,
false,
DL))
4129 if (FalseSI->getTrueValue() == TrueVal && FalseSI->hasOneUse()) {
4146 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(0))) {
4147 if (TrueBOSI->getCondition() == CondVal) {
4153 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(1))) {
4154 if (TrueBOSI->getCondition() == CondVal) {
4165 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(0))) {
4166 if (FalseBOSI->getCondition() == CondVal) {
4172 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(1))) {
4173 if (FalseBOSI->getCondition() == CondVal) {
4186 SI.swapProfMetadata();
4201 if (Known.One.isOne())
4203 if (Known.Zero.isOne())
4211 if (
Value *V = foldSelectCmpXchg(SI))
4229 if (
Value *V = foldRoundUpIntegerWithPow2Alignment(SI,
Builder))
4242 auto *MaskedInst = cast<IntrinsicInst>(TrueVal);
4243 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
4244 MaskedInst->setArgOperand(3, FalseVal );
4259 bool CanMergeSelectIntoLoad =
false;
4263 if (CanMergeSelectIntoLoad) {
4264 auto *MaskedInst = cast<IntrinsicInst>(FalseVal);
4265 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
4266 MaskedInst->setArgOperand(3, TrueVal );
4298 auto FoldSelectWithAndOrCond = [&](
bool IsAnd,
Value *
A,
4306 if (
ICmpInst *Cmp = dyn_cast<ICmpInst>(
B))
4307 if (
Value *V = canonicalizeSPF(*Cmp, TrueVal, FalseVal, *
this))
4309 IsAnd ? FalseVal : V);
4317 if (
Instruction *
I = FoldSelectWithAndOrCond(
true, LHS, RHS))
4319 if (
Instruction *
I = FoldSelectWithAndOrCond(
true, RHS, LHS))
4322 if (
Instruction *
I = FoldSelectWithAndOrCond(
false, LHS, RHS))
4324 if (
Instruction *
I = FoldSelectWithAndOrCond(
false, RHS, LHS))
4330 if (
Instruction *
I = FoldSelectWithAndOrCond(
true, LHS, RHS))
4333 if (
Instruction *
I = FoldSelectWithAndOrCond(
false, LHS, RHS))
4340 return BinaryOperator::CreateXor(CondVal, FalseVal);
4345 (!isa<Constant>(TrueVal) || !isa<Constant>(FalseVal))) {
4349 CC.AffectedValues.insert(V);
4352 if (!
CC.AffectedValues.empty()) {
4353 if (!isa<Constant>(TrueVal) &&
4354 hasAffectedValue(TrueVal,
CC.AffectedValues, 0)) {
4362 if (!isa<Constant>(FalseVal) &&
4363 hasAffectedValue(FalseVal,
CC.AffectedValues, 0)) {
4378 if (TrueVal == Trunc)
4380 if (FalseVal == Trunc)
4384 if (TrueVal == Trunc)
4387 if (FalseVal == Trunc)
SmallVector< AArch64_IMM::ImmInsnModel, 4 > Insn
AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
This file provides internal interfaces used to implement the InstCombine.
static Value * canonicalizeSaturatedAdd(ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
static Instruction * foldSetClearBits(SelectInst &Sel, InstCombiner::BuilderTy &Builder)
Canonicalize a set or clear of a masked set of constant bits to select-of-constants form.
static Instruction * foldSelectICmpAndAnd(Type *SelType, const ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
We want to turn: (select (icmp eq (and X, Y), 0), (and (lshr X, Z), 1), 1) into: zext (icmp ne i32 (a...
static unsigned getSelectFoldableOperands(BinaryOperator *I)
We want to turn code that looks like this: C = or A, B D = select cond, C, A into: C = select cond,...
static Instruction * foldSelectZeroOrMul(SelectInst &SI, InstCombinerImpl &IC)
static Value * canonicalizeSaturatedSubtract(const ICmpInst *ICI, const Value *TrueVal, const Value *FalseVal, InstCombiner::BuilderTy &Builder)
Transform patterns such as (a > b) ? a - b : 0 into usub.sat(a, b).
static Value * foldAbsDiff(ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
Try to match patterns with select and subtract as absolute difference.
static Instruction * foldSelectBinOpIdentity(SelectInst &Sel, const TargetLibraryInfo &TLI, InstCombinerImpl &IC)
Replace a select operand based on an equality comparison with the identity constant of a binop.
static Value * foldSelectICmpAndZeroShl(const ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
We want to turn: (select (icmp eq (and X, C1), 0), 0, (shl [nsw/nuw] X, C2)); iff C1 is a mask and th...
static Value * foldSelectICmpAndBinOp(const ICmpInst *IC, Value *TrueVal, Value *FalseVal, InstCombiner::BuilderTy &Builder)
We want to turn: (select (icmp eq (and X, C1), 0), Y, (BinOp Y, C2)) into: IF C2 u>= C1 (BinOp Y,...
static Value * foldSelectICmpLshrAshr(const ICmpInst *IC, Value *TrueVal, Value *FalseVal, InstCombiner::BuilderTy &Builder)
We want to turn: (select (icmp sgt x, C), lshr (X, Y), ashr (X, Y)); iff C s>= -1 (select (icmp slt x...
static bool isSelect01(const APInt &C1I, const APInt &C2I)
static Value * foldSelectICmpAnd(SelectInst &Sel, ICmpInst *Cmp, InstCombiner::BuilderTy &Builder)
This folds: select (icmp eq (and X, C1)), TC, FC iff C1 is a power 2 and the difference between TC an...
This file provides the interface for the instcombine pass implementation.
uint64_t IntrinsicInst * II
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static const uint32_t IV[8]
bool bitwiseIsEqual(const APFloat &RHS) const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
bool isMinSignedValue() const
Determine if this is the smallest signed value.
uint64_t getZExtValue() const
Get zero extended value.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
unsigned getBitWidth() const
Return the number of bits in the APInt.
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
bool isMinValue() const
Determine if this is the smallest unsigned value.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
unsigned countLeadingZeros() const
unsigned logBase2() const
bool isMask(unsigned numBits) const
bool isMaxSignedValue() const
Determine if this is the largest signed value.
bool isNonNegative() const
Determine if this APInt Value is non-negative (>= 0)
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
bool isOne() const
Determine if this is a value of 1.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
bool isMaxValue() const
Determine if this is the largest unsigned value.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
MutableArrayRef< ResultElem > assumptions()
Access the list of assumption handles currently tracked for this function.
An instruction that atomically checks whether a specified value is in a memory location,...
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
BinaryOps getOpcode() const
static BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
static BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
This class represents a no-op cast from one type to another.
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ ICMP_ULT
unsigned less than
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
bool isFPPredicate() const
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Predicate getPredicate() const
Return the predicate for this instruction.
static bool isUnordered(Predicate predicate)
Determine if the predicate is an unordered operation.
Predicate getFlippedStrictnessPredicate() const
For predicate of kind "is X or equal to 0" returns the predicate "is X".
bool isIntPredicate() const
bool isRelational() const
Return true if the predicate is relational (not EQ or NE).
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
static Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)
Return the identity constant for a binary opcode.
static Constant * getNeg(Constant *C, bool HasNSW=false)
static ConstantInt * getTrue(LLVMContext &Context)
static ConstantInt * getFalse(LLVMContext &Context)
This class represents a range of values.
ConstantRange add(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an addition of a value in this ran...
bool icmp(CmpInst::Predicate Pred, const ConstantRange &Other) const
Does the predicate Pred hold between ranges this and Other? NOTE: false does not mean that inverse pr...
static ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)
Produce the exact range such that all values in the returned range satisfy the given predicate with a...
ConstantRange binaryNot() const
Return a new range representing the possible values resulting from a binary-xor of a value in this ra...
ConstantRange binaryOp(Instruction::BinaryOps BinOp, const ConstantRange &Other) const
Return a new range representing the possible values resulting from an application of the specified bi...
ConstantRange sub(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a subtraction of a value in this r...
This is an important base class in LLVM.
static Constant * mergeUndefsWith(Constant *C, Constant *Other)
Merges undefs of a Constant with another Constant, along with the undefs already present.
static Constant * getAllOnesValue(Type *Ty)
bool isOneValue() const
Returns true if the value is one.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Tagged union holding either a T or a Error.
Utility class for floating point operations which can have information about relaxed accuracy require...
FastMathFlags getFastMathFlags() const
Convenience function for getting all the fast-math flags.
Convenience struct for specifying and reasoning about fast-math flags.
static FastMathFlags intersectRewrite(FastMathFlags LHS, FastMathFlags RHS)
Intersect rewrite-based flags.
bool noSignedZeros() const
static FastMathFlags unionValue(FastMathFlags LHS, FastMathFlags RHS)
Union value flags.
void setNoSignedZeros(bool B=true)
This class represents a freeze function that returns random concrete value if an operand is either a ...
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Value * getPointerOperand()
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Type * getSourceElementType() const
GEPNoWrapFlags getNoWrapFlags() const
Get the nowrap flags for the GEP instruction.
uint64_t getType(const MachineInstr &MI) const
This instruction compares its operands according to the predicate given to the constructor.
CmpPredicate getSwappedCmpPredicate() const
static bool isLT(Predicate P)
Return true if the predicate is SLT or ULT.
CmpPredicate getInverseCmpPredicate() const
static bool isGT(Predicate P)
Return true if the predicate is SGT or UGT.
bool isEquality() const
Return true if this predicate is either EQ or NE.
static bool isEquality(Predicate P)
Return true if this predicate is either EQ or NE.
bool isRelational() const
Return true if the predicate is relational (not EQ or NE).
Common base class shared among various IRBuilders.
CallInst * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with 1 operand which is mangled on its type.
Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with 2 operands which is mangled on the first type.
Value * CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
Value * CreateFAdd(Value *L, Value *R, const Twine &Name="", MDNode *FPMD=nullptr)
Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")
Return a vector value that contains.
ConstantInt * getTrue()
Get the constant value for i1 true.
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
Value * CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Value * CreateFreeze(Value *V, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
void setFastMathFlags(FastMathFlags NewFMF)
Set the fast-math flags to be used with generated fp-math operators.
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateIsNeg(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg < 0.
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateLogicalAnd(Value *Cond1, Value *Cond2, const Twine &Name="")
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateLogicalOr(Value *Cond1, Value *Cond2, const Twine &Name="")
Value * CreateFNeg(Value *V, const Twine &Name="", MDNode *FPMathTag=nullptr)
Instruction * foldSelectToCmp(SelectInst &SI)
bool fmulByZeroIsZero(Value *MulVal, FastMathFlags FMF, const Instruction *CtxI) const
Check if fmul MulVal, +0.0 will yield +0.0 (or signed zero is ignorable).
KnownFPClass computeKnownFPClass(Value *Val, FastMathFlags FMF, FPClassTest Interested=fcAllFlags, const Instruction *CtxI=nullptr, unsigned Depth=0) const
Instruction * foldSelectEqualityTest(SelectInst &SI)
Instruction * foldSelectValueEquivalence(SelectInst &SI, CmpInst &CI)
Instruction * foldOpIntoPhi(Instruction &I, PHINode *PN, bool AllowMultipleUses=false)
Given a binary operator, cast instruction, or select which has a PHI node as operand #0,...
Instruction * foldVectorSelect(SelectInst &Sel)
Value * SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, APInt &PoisonElts, unsigned Depth=0, bool AllowMultipleUsers=false) override
The specified value produces a vector with any number of elements.
Instruction * foldSPFofSPF(Instruction *Inner, SelectPatternFlavor SPF1, Value *A, Value *B, Instruction &Outer, SelectPatternFlavor SPF2, Value *C)
Instruction * foldSelectOpOp(SelectInst &SI, Instruction *TI, Instruction *FI)
We have (select c, TI, FI), and we know that TI and FI have the same opcode.
bool replaceInInstruction(Value *V, Value *Old, Value *New, unsigned Depth=0)
Instruction * foldSelectInstWithICmp(SelectInst &SI, ICmpInst *ICI)
bool sinkNotIntoOtherHandOfLogicalOp(Instruction &I)
Constant * getLosslessTrunc(Constant *C, Type *TruncTy, unsigned ExtOp)
Instruction * foldSelectIntoOp(SelectInst &SI, Value *, Value *)
Try to fold the select into one of the operands to allow further optimization.
Instruction * visitSelectInst(SelectInst &SI)
Instruction * foldSelectOfBools(SelectInst &SI)
Instruction * foldSelectExtConst(SelectInst &Sel)
The core instruction combiner logic.
const DataLayout & getDataLayout() const
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, unsigned Depth=0, const Instruction *CxtI=nullptr)
Instruction * InsertNewInstBefore(Instruction *New, BasicBlock::iterator Old)
Inserts an instruction New before instruction Old.
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
static bool shouldAvoidAbsorbingNotIntoSelect(const SelectInst &SI)
static std::optional< std::pair< CmpPredicate, Constant * > > getFlippedStrictnessPredicateAndConstant(CmpPredicate Pred, Constant *C)
void replaceUse(Use &U, Value *NewValue)
Replace use and add the previously used value to the worklist.
static bool isCanonicalPredicate(CmpPredicate Pred)
Predicate canonicalization reduces the number of patterns that need to be matched by other transforms...
InstructionWorklist & Worklist
A worklist of the instructions that need to be simplified.
void addToWorklist(Instruction *I)
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth, const Instruction *CxtI) const
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
const SimplifyQuery & getSimplifyQuery() const
static Constant * AddOne(Constant *C)
Add one to a Constant.
void add(Instruction *I)
Add instruction to the worklist.
void push(Instruction *I)
Push the instruction onto the worklist stack.
bool hasNoNaNs() const LLVM_READONLY
Determine whether the no-NaNs flag is set.
bool hasNoInfs() const LLVM_READONLY
Determine whether the no-infs flag is set.
bool isSameOperationAs(const Instruction *I, unsigned flags=0) const LLVM_READONLY
This function determines if the specified instruction executes the same operation as the current one.
void setHasNoSignedZeros(bool B)
Set or clear the no-signed-zeros flag on this instruction, which must be an operator which supports t...
bool hasNoSignedZeros() const LLVM_READONLY
Determine whether the no-signed-zeros flag is set.
void copyIRFlags(const Value *V, bool IncludeWrapFlags=true)
Convenience method to copy supported exact, fast-math, and (optionally) wrapping flags from V to this...
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction.
void setHasNoNaNs(bool B)
Set or clear the no-nans flag on this instruction, which must be an operator which supports this flag...
bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
void swapProfMetadata()
If the instruction has "branch_weights" MD_prof metadata and the MDNode has three operands (including...
void setHasNoInfs(bool B)
Set or clear the no-infs flag on this instruction, which must be an operator which supports this flag...
FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void dropPoisonGeneratingFlags()
Drops flags that may cause this instruction to evaluate to poison despite having non-poison inputs.
const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
A wrapper class for inspecting calls to intrinsic functions.
A Module instance is used to store all the information related to an LLVM module.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
This class represents a sign extension of integer types.
This class represents the LLVM 'select' instruction.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, Instruction *MDFrom=nullptr)
const Value * getFalseValue() const
void swapValues()
Swap the true and false values of the select instruction.
const Value * getCondition() const
const Value * getTrueValue() const
bool insert(const value_type &X)
Insert a new element into the SetVector.
This instruction constructs a fixed permutation of two input vectors.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool contains(ConstPtrType Ptr) const
A SetVector that performs no allocations if smaller than a certain size.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Provides information about what library functions are available for the current target.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
static IntegerType * getInt1Ty(LLVMContext &C)
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
static UnaryOperator * CreateFNegFMF(Value *Op, Instruction *FMFSource, const Twine &Name="", InsertPosition InsertBefore=nullptr)
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
const Value * DoPHITranslation(const BasicBlock *CurBB, const BasicBlock *PredBB) const
Translate PHI node to its predecessor from the given basic block.
bool hasOneUse() const
Return true if there is exactly one use of this value.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
Represents an op.with.overflow intrinsic.
This class represents zero extension of integer types.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
int getMinValue(MCInstrInfo const &MCII, MCInst const &MCI)
Return the minimum value of an extendable operand.
int getMaxValue(MCInstrInfo const &MCII, MCInst const &MCI)
Return the maximum value of an extendable operand.
Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
BinaryOp_match< cst_pred_ty< is_all_ones, false >, ValTy, Instruction::Xor, true > m_NotForbidPoison(const ValTy &V)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
CmpClass_match< LHS, RHS, FCmpInst > m_FCmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FMul, true > m_c_FMul(const LHS &L, const RHS &R)
Matches FMul with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FSub > m_FSub(const LHS &L, const RHS &R)
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power-of-2.
match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
match_combine_or< CastInst_match< OpTy, ZExtInst >, OpTy > m_ZExtOrSelf(const OpTy &Op)
bool match(Val *V, const Pattern &P)
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
constantexpr_match m_ConstantExpr()
Match a constant expression or a constant that contains a constant expression.
specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)
CmpClass_match< LHS, RHS, ICmpInst, true > m_c_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
OverflowingBinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWNeg(const ValTy &V)
Matches a 'Neg' as 'sub nsw 0, V'.
TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)
Matches ExtractElementInst.
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
match_combine_or< MaxMin_match< FCmpInst, LHS, RHS, ofmin_pred_ty >, MaxMin_match< FCmpInst, LHS, RHS, ufmin_pred_ty > > m_OrdOrUnordFMin(const LHS &L, const RHS &R)
Match an 'ordered' or 'unordered' floating point minimum function.
BinOpPred_match< LHS, RHS, is_logical_shift_op > m_LogicalShift(const LHS &L, const RHS &R)
Matches logical shift operations.
match_combine_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)
Combine two pattern matchers matching L && R.
MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > m_SMin(const LHS &L, const RHS &R)
cst_pred_ty< is_any_apint > m_AnyIntegralConstant()
Match an integer or vector with any integral constant.
bind_ty< WithOverflowInst > m_WithOverflowInst(WithOverflowInst *&I)
Match a with overflow intrinsic, capturing it if we match.
BinaryOp_match< LHS, RHS, Instruction::Xor, true > m_c_Xor(const LHS &L, const RHS &R)
Matches an Xor with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::FAdd > m_FAdd(const LHS &L, const RHS &R)
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
cst_pred_ty< is_zero_int > m_ZeroInt()
Match an integer 0 or a vector with all elements equal to 0.
apint_match m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
NoWrapTrunc_match< OpTy, TruncInst::NoSignedWrap > m_NSWTrunc(const OpTy &Op)
Matches trunc nsw.
OneUse_match< T > m_OneUse(const T &SubPattern)
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
BinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub > m_Neg(const ValTy &V)
Matches a 'Neg' as 'sub 0, V'.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
match_combine_and< class_match< Constant >, match_unless< constantexpr_match > > m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2, Opnd3 >::Ty m_MaskedLoad(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2, const Opnd3 &Op3)
Matches MaskedLoad Intrinsic.
SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
apint_match m_APIntForbidPoison(const APInt *&Res)
Match APInt while forbidding poison in splat vector constants.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
BinOpPred_match< LHS, RHS, is_bitwiselogic_op, true > m_c_BitwiseLogic(const LHS &L, const RHS &R)
Matches bitwise logic operations in either order.
MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty > m_UMax(const LHS &L, const RHS &R)
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
auto m_c_LogicalOp(const LHS &L, const RHS &R)
Matches either L && R or L || R with LHS and RHS in either order.
NoWrapTrunc_match< OpTy, TruncInst::NoUnsignedWrap > m_NUWTrunc(const OpTy &Op)
Matches trunc nuw.
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
apfloat_match m_APFloatAllowPoison(const APFloat *&Res)
Match APFloat while allowing poison in splat vector constants.
match_combine_or< MaxMin_match< FCmpInst, LHS, RHS, ofmax_pred_ty >, MaxMin_match< FCmpInst, LHS, RHS, ufmax_pred_ty > > m_OrdOrUnordFMax(const LHS &L, const RHS &R)
Match an 'ordered' or 'unordered' floating point maximum function.
CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty > m_SMax(const LHS &L, const RHS &R)
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
AnyBinaryOp_match< LHS, RHS, true > m_c_BinOp(const LHS &L, const RHS &R)
Matches a BinaryOperator with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
cstfp_pred_ty< is_pos_zero_fp > m_PosZeroFP()
Match a floating-point positive zero.
LogicalOp_match< LHS, RHS, Instruction::And, true > m_c_LogicalAnd(const LHS &L, const RHS &R)
Matches L && R with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
m_Intrinsic_Ty< Opnd0 >::Ty m_VecReverse(const Opnd0 &Op0)
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
match_combine_or< match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty >, MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > >, match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty >, MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > > > m_MaxOrMin(const LHS &L, const RHS &R)
class_match< BasicBlock > m_BasicBlock()
Match an arbitrary basic block value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)
auto m_Undef()
Match an arbitrary undef constant.
BinaryOp_match< cst_pred_ty< is_all_ones >, ValTy, Instruction::Xor, true > m_Not(const ValTy &V)
Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
BinOpPred_match< LHS, RHS, is_bitwiselogic_op > m_BitwiseLogic(const LHS &L, const RHS &R)
Matches bitwise logic operations.
LogicalOp_match< LHS, RHS, Instruction::Or, true > m_c_LogicalOr(const LHS &L, const RHS &R)
Matches L || R with LHS and RHS in either order.
SpecificCmpClass_match< LHS, RHS, ICmpInst, true > m_c_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
ElementWiseBitCast_match< OpTy > m_ElementWiseBitCast(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > m_UMin(const LHS &L, const RHS &R)
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2, Opnd3 >::Ty m_MaskedGather(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2, const Opnd3 &Op3)
Matches MaskedGather Intrinsic.
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
cst_pred_ty< icmp_pred_with_threshold > m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold)
Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.
ElementType
The element type of an SRV or UAV resource.
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
bool isSafeToSpeculativelyExecuteWithVariableReplaced(const Instruction *I)
Don't use information from its non-constant operands.
bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS, bool &TrueIfSigned)
Given an exploded icmp instruction, return true if the comparison only checks the sign bit.
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Instruction *I=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
CmpInst::Predicate getMinMaxPred(SelectPatternFlavor SPF, bool Ordered=false)
Return the canonical comparison predicate for the specified minimum/maximum flavor.
bool isGuaranteedNotToBeUndef(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be undef, but may be poison.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)
Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...
constexpr unsigned MaxAnalysisRecursionDepth
SelectPatternFlavor
Specific patterns of select instructions we can match.
@ SPF_ABS
Floating point maxnum.
@ SPF_NABS
Absolute value.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool impliesPoison(const Value *ValAssumedPoison, const Value *V)
Return true if V is poison given that ValAssumedPoison is already poison.
SelectPatternResult getSelectPattern(CmpInst::Predicate Pred, SelectPatternNaNBehavior NaNBehavior=SPNB_NA, bool Ordered=false)
Determine the pattern for predicate X Pred Y ? X : Y.
SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)
Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind and providing the out param...
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
Value * simplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an And, fold the result or return null.
bool isKnownInversion(const Value *X, const Value *Y)
Return true iff:
bool isNotCrossLaneOperation(const Instruction *I)
Return true if the instruction doesn't potentially cross vector lanes.
Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
constexpr int PoisonMaskElem
Intrinsic::ID getMinMaxIntrinsic(SelectPatternFlavor SPF)
Convert given SPF to equivalent min/max intrinsic.
@ Or
Bitwise or logical OR of integers.
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
std::optional< DecomposedBitTest > decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate Pred, bool LookThroughTrunc=true, bool AllowNonZeroC=false)
Decompose an icmp into the form ((X & Mask) pred C) if possible.
void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
DWARFExpression::Operation Op
constexpr unsigned BitWidth
SelectPatternResult matchDecomposedSelectPattern(CmpInst *CmpI, Value *TrueVal, Value *FalseVal, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)
Determine the pattern that a select with the given compare as its predicate and given values as its t...
Value * simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp, const SimplifyQuery &Q, bool AllowRefinement, SmallVectorImpl< Instruction * > *DropFlags=nullptr)
See if V simplifies when its operand Op is replaced with RepOp.
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
bool cannotBeNegativeZero(const Value *V, unsigned Depth, const SimplifyQuery &SQ)
Return true if we can prove that the specified FP value is never equal to -0.0.
bool isKnownNeverNaN(const Value *V, unsigned Depth, const SimplifyQuery &SQ)
Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...
bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
bool isCheckForZeroAndMulWithOverflow(Value *Op0, Value *Op1, bool IsAnd, Use *&Y)
Match one of the patterns up to the select/logic op: Op0 = icmp ne i4 X, 0 Agg = call { i4,...
Value * simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, const SimplifyQuery &Q)
Given operands for a SelectInst, fold the result or return null.
std::optional< bool > isImpliedCondition(const Value *LHS, const Value *RHS, const DataLayout &DL, bool LHSIsTrue=true, unsigned Depth=0)
Return true if RHS is known to be implied true by LHS.
void findValuesAffectedByCondition(Value *Cond, bool IsAssume, function_ref< void(Value *)> InsertAffected)
Call InsertAffected on all Values whose known bits / value may be affected by the condition Cond.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Evaluate query assuming this condition holds.
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...
bool isConstant() const
Returns true if we know the value of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
bool isKnownNeverInfinity() const
Return true if it's known this can never be an infinity.
bool isKnownNeverNaN() const
Return true if it's known this can never be a nan.
bool signBitIsZeroOrNaN() const
Return true if the sign bit must be 0, ignoring the sign of nans.
SelectPatternFlavor Flavor
bool Ordered
Only applicable if Flavor is SPF_FMINNUM or SPF_FMAXNUM.
static bool isMinOrMax(SelectPatternFlavor SPF)
When implementing this min/max pattern as fcmp; select, does the fcmp have to be ordered?
SimplifyQuery getWithCondContext(const CondContext &CC) const
SimplifyQuery getWithInstruction(const Instruction *I) const