47#define DEBUG_TYPE "instcombine"
51using namespace PatternMatch;
68 IsEq = Pred == ICmpInst::ICMP_EQ;
69 else if (Pred == FCmpInst::FCMP_OEQ)
71 else if (Pred == FCmpInst::FCMP_UNE)
101 if (isa<FPMathOperator>(BO))
127 const APInt *SelTC, *SelFC;
136 const APInt &TC = *SelTC;
137 const APInt &FC = *SelFC;
138 if (!TC.
isZero() && !FC.isZero()) {
150 Constant *TCC = ConstantInt::get(SelType, TC);
151 Constant *FCC = ConstantInt::get(SelType, FC);
152 Constant *MaskC = ConstantInt::get(SelType, AndMask);
153 for (
auto Opc : {Instruction::Or, Instruction::Xor, Instruction::Add,
173 unsigned ValZeros = ValC.
logBase2();
174 unsigned AndZeros = AndMask.
logBase2();
175 bool ShouldNotVal = !TC.
isZero();
176 bool NeedShift = ValZeros != AndZeros;
183 if (CreateAnd + ShouldNotVal + NeedShift + NeedZExtTrunc >
189 V = Builder.
CreateAnd(V, ConstantInt::get(V->getType(), AndMask));
193 if (ValZeros > AndZeros) {
195 V = Builder.
CreateShl(V, ValZeros - AndZeros);
196 }
else if (ValZeros < AndZeros) {
197 V = Builder.
CreateLShr(V, AndZeros - ValZeros);
222 switch (
I->getOpcode()) {
223 case Instruction::Add:
224 case Instruction::FAdd:
225 case Instruction::Mul:
226 case Instruction::FMul:
227 case Instruction::And:
228 case Instruction::Or:
229 case Instruction::Xor:
231 case Instruction::Sub:
232 case Instruction::FSub:
233 case Instruction::FDiv:
234 case Instruction::Shl:
235 case Instruction::LShr:
236 case Instruction::AShr:
266 if (
auto *CondVTy = dyn_cast<VectorType>(CondTy)) {
268 CondVTy->getElementCount() !=
269 cast<VectorType>(FIOpndTy)->getElementCount())
280 if (TI->
getOpcode() != Instruction::BitCast &&
293 SI.getName() +
".v", &SI);
298 Value *OtherOpT, *OtherOpF;
301 bool Swapped =
false) ->
Value * {
302 assert(!(Commute && Swapped) &&
303 "Commute and Swapped can't set at the same time");
308 MatchIsOpZero =
true;
313 MatchIsOpZero =
false;
318 if (!Commute && !Swapped)
327 MatchIsOpZero =
true;
332 MatchIsOpZero =
false;
346 FMF |= SI.getFastMathFlags();
349 if (
auto *NewSelI = dyn_cast<Instruction>(NewSel))
350 NewSelI->setFastMathFlags(FMF);
351 Instruction *NewFNeg = UnaryOperator::CreateFNeg(NewSel);
360 auto *
TII = dyn_cast<IntrinsicInst>(TI);
361 auto *FII = dyn_cast<IntrinsicInst>(FI);
362 if (
TII && FII &&
TII->getIntrinsicID() == FII->getIntrinsicID()) {
364 if (
Value *MatchOp = getCommonOp(TI, FI,
true)) {
376 if (
TII->getIntrinsicID() == Intrinsic::ldexp) {
377 Value *LdexpVal0 =
TII->getArgOperand(0);
378 Value *LdexpExp0 =
TII->getArgOperand(1);
379 Value *LdexpVal1 = FII->getArgOperand(0);
380 Value *LdexpExp1 = FII->getArgOperand(1);
384 FMF &= cast<FPMathOperator>(FII)->getFastMathFlags();
391 TII->
getType(), Intrinsic::ldexp, {SelectVal, SelectExp});
398 auto CreateCmpSel = [&](std::optional<CmpPredicate>
P,
407 SI.getName() +
".v", &SI);
435 (!isa<BinaryOperator>(TI) && !isa<GetElementPtrInst>(TI)) ||
457 auto *BO = dyn_cast<BinaryOperator>(TI);
461 if (BO->getOpcode() == Instruction::SDiv ||
462 BO->getOpcode() == Instruction::SRem || MatchIsOpZero)
468 SI.getName() +
".v", &SI);
469 Value *Op0 = MatchIsOpZero ? MatchOp : NewSI;
470 Value *Op1 = MatchIsOpZero ? NewSI : MatchOp;
471 if (
auto *BO = dyn_cast<BinaryOperator>(TI)) {
477 if (
auto *TGEP = dyn_cast<GetElementPtrInst>(TI)) {
478 auto *FGEP = cast<GetElementPtrInst>(FI);
479 Type *ElementType = TGEP->getSourceElementType();
481 ElementType, Op0, Op1, TGEP->getNoWrapFlags() & FGEP->getNoWrapFlags());
502 auto *TVI = dyn_cast<BinaryOperator>(TrueVal);
503 if (!TVI || !TVI->hasOneUse() || isa<Constant>(FalseVal))
507 unsigned OpToFold = 0;
508 if ((SFO & 1) && FalseVal == TVI->getOperand(0))
510 else if ((SFO & 2) && FalseVal == TVI->getOperand(1))
517 if (isa<FPMathOperator>(&SI))
518 FMF = SI.getFastMathFlags();
520 TVI->getOpcode(), TVI->getType(),
true, FMF.
noSignedZeros());
521 Value *OOp = TVI->getOperand(2 - OpToFold);
526 if (isa<Constant>(OOp) &&
527 (!OOpIsAPInt || !
isSelect01(
C->getUniqueInteger(), *OOpC)))
536 if (isa<FPMathOperator>(&SI) &&
541 Swapped ? OOp :
C,
"", &SI);
542 if (isa<FPMathOperator>(&SI))
543 cast<Instruction>(NewSel)->setFastMathFlags(FMF);
548 if (isa<FPMathOperator>(&SI)) {
559 if (
Instruction *R = TryFoldSelectIntoOp(SI, TrueVal, FalseVal,
false))
562 if (
Instruction *R = TryFoldSelectIntoOp(SI, FalseVal, TrueVal,
true))
575 const Value *CmpLHS = Cmp->getOperand(0);
576 const Value *CmpRHS = Cmp->getOperand(1);
583 if (CmpRHS == TVal) {
590 if (!(CmpLHS == TVal && isa<Instruction>(FVal)))
595 cast<Instruction>(FVal)->setHasNoUnsignedWrap(
false);
601 cast<Instruction>(FVal)->setHasNoUnsignedWrap(
false);
607 cast<Instruction>(FVal)->setHasNoSignedWrap(
false);
616 cast<Instruction>(FVal)->setHasNoSignedWrap(
false);
617 cast<Instruction>(FVal)->setHasNoUnsignedWrap(
false);
635 if (!(Cmp->hasOneUse() && Cmp->getOperand(0)->hasOneUse() &&
667 Constant *One = ConstantInt::get(SelType, 1);
672 return new ZExtInst(ICmpNeZero, SelType);
694 const APInt *C2, *C1;
704 auto *FI = dyn_cast<Instruction>(FVal);
708 FI->setHasNoSignedWrap(
false);
709 FI->setHasNoUnsignedWrap(
false);
744 const auto *Ashr = cast<Instruction>(FalseVal);
746 bool IsExact = Ashr->isExact() && cast<Instruction>(TrueVal)->isExact();
775 const APInt &AndMask,
bool CreateAnd,
778 if (!TrueVal->getType()->isIntOrIntVectorTy())
781 unsigned C1Log = AndMask.
logBase2();
788 BinOp = cast<BinaryOperator>(FalseVal);
792 BinOp = cast<BinaryOperator>(TrueVal);
802 if (IdentityC ==
nullptr || !IdentityC->isNullValue())
807 bool NeedShift = C1Log != C2Log;
808 bool NeedZExtTrunc =
Y->getType()->getScalarSizeInBits() !=
809 V->getType()->getScalarSizeInBits();
812 if ((NeedShift + NeedXor + NeedZExtTrunc + CreateAnd) >
818 V = Builder.
CreateAnd(V, ConstantInt::get(V->getType(), AndMask));
824 }
else if (C1Log > C2Log) {
834 if (
auto *BO = dyn_cast<BinaryOperator>(Res))
835 BO->copyIRFlags(BinOp);
854 Constant *OrC = ConstantInt::get(Ty, *
C);
856 return BinaryOperator::CreateOr(
T, NewSel);
863 Constant *OrC = ConstantInt::get(Ty, *
C);
865 return BinaryOperator::CreateOr(
F, NewSel);
886 auto *CondVal = SI.getCondition();
887 auto *TrueVal = SI.getTrueValue();
888 auto *FalseVal = SI.getFalseValue();
906 auto *TrueValC = dyn_cast<Constant>(TrueVal);
907 if (TrueValC ==
nullptr || !isa<Instruction>(FalseVal))
925 auto *ZeroC = cast<Constant>(cast<Instruction>(CondVal)->getOperand(1));
933 auto *FalseValI = cast<Instruction>(FalseVal);
938 FalseValI->getOperand(0) ==
Y
940 : (FalseValI->getOperand(1) ==
Y ? 1 : 2),
949 const Value *TrueVal,
950 const Value *FalseVal,
971 ConstantInt::get(
A->getType(), 1));
985 "Unexpected isUnsigned predicate!");
991 bool IsNegative =
false;
1004 if (IsNegative && !TrueVal->hasOneUse() && !ICI->
hasOneUse())
1017 if (!Cmp->hasOneUse())
1021 Value *Cmp0 = Cmp->getOperand(0);
1022 Value *Cmp1 = Cmp->getOperand(1);
1043 Intrinsic::uadd_sat, Cmp0, ConstantInt::get(Cmp0->
getType(), 1));
1054 ConstantInt::get(Cmp0->
getType(), *
C));
1064 ConstantInt::get(Cmp0->
getType(), *
C));
1074 ConstantInt::get(Cmp0->
getType(), *
C));
1121 auto *TI = dyn_cast<Instruction>(TVal);
1122 auto *FI = dyn_cast<Instruction>(FVal);
1128 Value *
A = Cmp->getOperand(0);
1129 Value *
B = Cmp->getOperand(1);
1142 (TI->hasNoSignedWrap() || TI->hasNoUnsignedWrap()) &&
1143 (FI->hasNoSignedWrap() || FI->hasNoUnsignedWrap())) {
1150 TI->setHasNoUnsignedWrap(
false);
1151 if (!TI->hasNoSignedWrap())
1152 TI->setHasNoSignedWrap(TI->hasOneUse());
1180 if (!
match(FalseVal,
1184 if (!
match(Ctlz, m_Intrinsic<Intrinsic::ctlz>()))
1191 auto *
II = cast<IntrinsicInst>(Ctlz);
1196 II->getModule(), Intrinsic::cttz,
II->getType());
1228 Value *Count =
nullptr;
1236 if (!
match(Count, m_Intrinsic<Intrinsic::cttz>(
m_Value(
X))) &&
1258 II->dropPoisonGeneratingAnnotations();
1270 II->dropUBImplyingAttrsAndMetadata();
1281 if (!
TrueVal->getType()->isIntOrIntVectorTy())
1318 assert(!isa<Constant>(Old) &&
"Only replace non-constant values");
1320 auto *
I = dyn_cast<Instruction>(V);
1321 if (!
I || !
I->hasOneUse() ||
1329 bool Changed =
false;
1330 for (
Use &U :
I->operands()) {
1363 bool Swapped =
false;
1364 if (
Cmp.isEquivalence(
true)) {
1367 }
else if (!
Cmp.isEquivalence()) {
1371 Value *CmpLHS =
Cmp.getOperand(0), *CmpRHS =
Cmp.getOperand(1);
1372 auto ReplaceOldOpWithNewOp = [&](
Value *OldOp,
1380 if (TrueVal == OldOp && (isa<Constant>(OldOp) || !isa<Constant>(NewOp)))
1397 (isa<Instruction>(TrueVal) &&
1398 is_contained(cast<Instruction>(TrueVal)->operands(), V))) {
1419 if (
Instruction *R = ReplaceOldOpWithNewOp(CmpLHS, CmpRHS))
1421 if (
Instruction *R = ReplaceOldOpWithNewOp(CmpRHS, CmpLHS))
1424 auto *FalseInst = dyn_cast<Instruction>(FalseVal);
1439 &DropFlags) == TrueVal ||
1442 &DropFlags) == TrueVal) {
1444 I->dropPoisonGeneratingAnnotations();
1489 cast<ICmpInst>(XeqY)->setSameSign(
false);
1524 if (!isa<SelectInst>(Sel1)) {
1565 if (Cmp00->
getType() !=
X->getType() &&
X->hasOneUse())
1573 else if (!
match(Cmp00,
1581 Value *ReplacementLow, *ReplacementHigh;
1618 std::swap(ReplacementLow, ReplacementHigh);
1624 "Unexpected predicate type.");
1632 "Unexpected predicate type.");
1634 std::swap(ThresholdLowIncl, ThresholdHighExcl);
1650 if (
X->getType() != Sel0.
getType()) {
1660 assert(ReplacementLow && ReplacementHigh &&
1661 "Constant folding of ImmConstant cannot fail");
1667 Value *MaybeReplacedLow =
1673 ShouldReplaceHigh, ReplacementHigh, MaybeReplacedLow);
1717 Value *SelVal0, *SelVal1;
1726 auto MatchesSelectValue = [SelVal0, SelVal1](
Constant *
C) {
1727 return C->isElementWiseEqual(SelVal0) ||
C->isElementWiseEqual(SelVal1);
1731 if (MatchesSelectValue(C0))
1736 if (!FlippedStrictness)
1740 if (!MatchesSelectValue(FlippedStrictness->second))
1749 Cmp.getName() +
".inv");
1760 if (!
Cmp->hasOneUse())
1790 Value *TVal =
SI.getTrueValue();
1791 Value *FVal =
SI.getFalseValue();
1825 Op->dropPoisonGeneratingFlags();
1829 if (
auto *MMI = dyn_cast<MinMaxIntrinsic>(
Op);
1830 MMI && MMI->getLHS() == V &&
match(MMI->getRHS(),
m_APInt(OpC))) {
1832 {InvDomCR, ConstantRange(*OpC)});
1834 MMI->dropPoisonGeneratingAnnotations();
1897 foldSelectWithExtremeEqCond(CmpLHS, CmpRHS, TrueVal, FalseVal))
1929 Opcode = BOp->getOpcode();
1930 IsIntrinsic =
false;
1944 Opcode =
II->getIntrinsicID();
1961 if (C3 == FoldBinaryOpOrIntrinsic(C1, C2)) {
1964 }
else if (Flipped && C3 == FoldBinaryOpOrIntrinsic(Flipped->second, C2)) {
1966 RHS = Flipped->second;
1981 if (
Instruction *BinOpInst = dyn_cast<Instruction>(BinOp)) {
1982 if (BinOpc == Instruction::Add || BinOpc == Instruction::Sub ||
1983 BinOpc == Instruction::Mul) {
1984 Instruction *OldBinOp = cast<BinaryOperator>(TrueVal);
1986 willNotOverflow(BinOpc, RHS, C2, *BinOpInst,
true))
1987 BinOpInst->setHasNoSignedWrap();
1989 willNotOverflow(BinOpc, RHS, C2, *BinOpInst,
false))
1990 BinOpInst->setHasNoUnsignedWrap();
2008static Instruction *foldICmpUSubSatWithAndForMostSignificantBitCmp(
2014 const APInt *Constant1, *Constant2;
2019 m_OneUse(m_Intrinsic<Intrinsic::usub_sat>(
2032 auto *Ty =
A->getType();
2040 APInt AdjAP1 = *Constant1 - MostSignificantBit + 1;
2041 APInt AdjAP2 = *Constant2 - MostSignificantBit + 1;
2043 auto *Adj1 = ConstantInt::get(Ty, AdjAP1);
2044 auto *Adj2 = ConstantInt::get(Ty, AdjAP2);
2049 Constant *MSBConst = ConstantInt::get(Ty, MostSignificantBit);
2050 return BinaryOperator::CreateAnd(
Or, MSBConst);
2057 canonicalizeSPF(*ICI,
SI.getTrueValue(),
SI.getFalseValue(), *
this))
2060 if (
Value *V = foldSelectInstWithICmpConst(SI, ICI,
Builder))
2063 if (
Value *V = canonicalizeClampLike(SI, *ICI,
Builder, *
this))
2067 tryToReuseConstantFromSelectInComparison(SI, *ICI, *
this))
2070 foldICmpUSubSatWithAndForMostSignificantBitCmp(SI, ICI,
Builder))
2074 bool Changed =
false;
2081 if (
Instruction *NewSel = foldSelectICmpEq(SI, ICI, *
this))
2096 SI.swapProfMetadata();
2119 if (
Value *V = foldSelectCttzCtlz(ICI, TrueVal, FalseVal, *
this))
2134 return Changed ? &
SI :
nullptr;
2147 if (
C ==
A ||
C ==
B) {
2162 Value *CondVal =
SI.getCondition();
2165 auto *TI = dyn_cast<Instruction>(TrueVal);
2166 auto *FI = dyn_cast<Instruction>(FalseVal);
2167 if (!TI || !FI || !TI->hasOneUse() || !FI->hasOneUse())
2171 if ((TI->getOpcode() == Instruction::Sub &&
2172 FI->getOpcode() == Instruction::Add) ||
2173 (TI->getOpcode() == Instruction::FSub &&
2174 FI->getOpcode() == Instruction::FAdd)) {
2177 }
else if ((FI->getOpcode() == Instruction::Sub &&
2178 TI->getOpcode() == Instruction::Add) ||
2179 (FI->getOpcode() == Instruction::FSub &&
2180 TI->getOpcode() == Instruction::FAdd)) {
2186 Value *OtherAddOp =
nullptr;
2187 if (SubOp->getOperand(0) == AddOp->
getOperand(0)) {
2189 }
else if (SubOp->getOperand(0) == AddOp->
getOperand(1)) {
2197 if (
SI.getType()->isFPOrFPVectorTy()) {
2198 NegVal = Builder.
CreateFNeg(SubOp->getOperand(1));
2199 if (
Instruction *NegInst = dyn_cast<Instruction>(NegVal)) {
2201 Flags &= SubOp->getFastMathFlags();
2202 NegInst->setFastMathFlags(Flags);
2205 NegVal = Builder.
CreateNeg(SubOp->getOperand(1));
2208 Value *NewTrueOp = OtherAddOp;
2209 Value *NewFalseOp = NegVal;
2213 SI.getName() +
".p", &SI);
2215 if (
SI.getType()->isFPOrFPVectorTy()) {
2217 BinaryOperator::CreateFAdd(SubOp->getOperand(0), NewSel);
2220 Flags &= SubOp->getFastMathFlags();
2224 return BinaryOperator::CreateAdd(SubOp->getOperand(0), NewSel);
2237 Value *CondVal =
SI.getCondition();
2249 auto IsSignedSaturateLimit = [&](
Value *Limit,
bool IsAdd) {
2259 auto IsZeroOrOne = [](
const APInt &
C) {
return C.isZero() ||
C.isOne(); };
2276 IsMinMax(TrueVal, FalseVal))
2283 IsMinMax(FalseVal, TrueVal))
2289 IsMinMax(TrueVal, FalseVal))
2294 IsMinMax(FalseVal, TrueVal))
2299 IsMinMax(FalseVal, TrueVal))
2304 IsMinMax(TrueVal, FalseVal))
2312 if (
II->getIntrinsicID() == Intrinsic::uadd_with_overflow &&
2315 NewIntrinsicID = Intrinsic::uadd_sat;
2316 else if (
II->getIntrinsicID() == Intrinsic::usub_with_overflow &&
2319 NewIntrinsicID = Intrinsic::usub_sat;
2320 else if (
II->getIntrinsicID() == Intrinsic::sadd_with_overflow &&
2321 IsSignedSaturateLimit(TrueVal,
true))
2330 NewIntrinsicID = Intrinsic::sadd_sat;
2331 else if (
II->getIntrinsicID() == Intrinsic::ssub_with_overflow &&
2332 IsSignedSaturateLimit(TrueVal,
false))
2341 NewIntrinsicID = Intrinsic::ssub_sat;
2346 NewIntrinsicID,
SI.getType());
2362 if (ExtOpcode != Instruction::ZExt && ExtOpcode != Instruction::SExt)
2368 Type *SmallType =
X->getType();
2370 auto *
Cmp = dyn_cast<CmpInst>(
Cond);
2372 (!Cmp ||
Cmp->getOperand(0)->getType() != SmallType))
2380 Value *TruncCVal = cast<Value>(TruncC);
2396 Value *CondVal =
SI.getCondition();
2398 auto *CondValTy = dyn_cast<FixedVectorType>(CondVal->
getType());
2402 unsigned NumElts = CondValTy->getNumElements();
2404 Mask.reserve(NumElts);
2405 for (
unsigned i = 0; i != NumElts; ++i) {
2415 Mask.push_back(i + NumElts);
2416 }
else if (isa<UndefValue>(Elt)) {
2436 auto *Ty = dyn_cast<VectorType>(Sel.
getType());
2468 if (TVal ==
A || TVal ==
B || FVal ==
A || FVal ==
B)
2485 if (TSrc ==
C && FSrc ==
D) {
2489 }
else if (TSrc ==
D && FSrc ==
C) {
2528 auto *Extract = dyn_cast<ExtractValueInst>(V);
2531 if (Extract->getIndices()[0] !=
I)
2533 return dyn_cast<AtomicCmpXchgInst>(Extract->getAggregateOperand());
2539 if (
auto *
Select = dyn_cast<SelectInst>(
SI.user_back()))
2540 if (
Select->getCondition() ==
SI.getCondition())
2541 if (
Select->getFalseValue() ==
SI.getTrueValue() ||
2542 Select->getTrueValue() ==
SI.getFalseValue())
2546 auto *CmpXchg = isExtractFromCmpXchg(
SI.getCondition(), 1);
2553 if (
auto *
X = isExtractFromCmpXchg(
SI.getTrueValue(), 0))
2554 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getFalseValue())
2555 return SI.getFalseValue();
2560 if (
auto *
X = isExtractFromCmpXchg(
SI.getFalseValue(), 0))
2561 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getTrueValue())
2562 return SI.getFalseValue();
2586 Value *SV0, *SV1, *SA0, *SA1;
2595 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2601 Or1->
getOpcode() == BinaryOperator::LShr &&
2602 "Illegal or(shift,shift) pair");
2617 bool IsFshl = (ShAmt == SA0);
2619 if ((IsFshl && TVal != SV0) || (!IsFshl && TVal != SV1))
2639 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
2661 assert(TC != FC &&
"Expected equal select arms to simplify");
2665 bool IsTrueIfSignSet;
2683 Value *MagArg = ConstantFP::get(SelType,
abs(*TC));
2690 if (!isa<VectorType>(Sel.
getType()))
2701 if (
auto *
I = dyn_cast<Instruction>(V))
2702 I->copyIRFlags(&Sel);
2705 M, Intrinsic::vector_reverse,
V->getType());
2713 return createSelReverse(
C,
X,
Y);
2717 return createSelReverse(
C,
X, FVal);
2722 return createSelReverse(
C, TVal,
Y);
2725 auto *VecTy = dyn_cast<FixedVectorType>(Sel.
getType());
2729 unsigned NumElts = VecTy->getNumElements();
2730 APInt PoisonElts(NumElts, 0);
2744 cast<ShuffleVectorInst>(TVal)->isSelect()) {
2758 cast<ShuffleVectorInst>(FVal)->isSelect()) {
2779 auto *IDomNode = DT[BB]->getIDom();
2785 Value *IfTrue, *IfFalse;
2801 if (TrueSucc == FalseSucc)
2822 if (
auto *Insn = dyn_cast<Instruction>(Inputs[Pred]))
2823 if (!DT.
dominates(Insn, Pred->getTerminator()))
2841 if (
auto *
I = dyn_cast<Instruction>(V))
2842 CandidateBlocks.
insert(
I->getParent());
2845 if (
auto *PN = foldSelectToPhiImpl(Sel, BB, DT, Builder))
2858 Value *CondVal =
SI.getCondition();
2863 Value *
Op, *RemRes, *Remainder;
2865 bool TrueIfSigned =
false;
2879 return BinaryOperator::CreateAnd(
Op,
Add);
2891 return FoldToBitwiseAnd(Remainder);
2900 return FoldToBitwiseAnd(ConstantInt::get(RemRes->
getType(), 2));
2936 Value *InnerCondVal =
SI.getCondition();
2937 Value *InnerTrueVal =
SI.getTrueValue();
2938 Value *InnerFalseVal =
SI.getFalseValue();
2940 "The type of inner condition must match with the outer.");
2942 return *Implied ? InnerTrueVal : InnerFalseVal;
2949 assert(
Op->getType()->isIntOrIntVectorTy(1) &&
2950 "Op must be either i1 or vector of i1.");
2951 if (
SI.getCondition()->getType() !=
Op->getType())
2953 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(SI,
Op, IsAnd,
DL))
2964 Value *CondVal =
SI.getCondition();
2966 bool ChangedFMF =
false;
2967 for (
bool Swap : {
false,
true}) {
2984 (cast<FPMathOperator>(CondVal)->hasNoNaNs() ||
SI.hasNoNaNs() ||
2987 cast<Instruction>(CondVal))))) {
3004 FastMathFlags FMF = cast<FPMathOperator>(CondVal)->getFastMathFlags();
3005 if (FMF.
noNaNs() && !
SI.hasNoNaNs()) {
3006 SI.setHasNoNaNs(
true);
3009 if (FMF.
noInfs() && !
SI.hasNoInfs()) {
3010 SI.setHasNoInfs(
true);
3015 if (!
SI.hasNoNaNs() && cast<FPMathOperator>(TrueVal)->hasNoNaNs() &&
3017 SI.setHasNoNaNs(
true);
3031 if (!
SI.hasNoSignedZeros() &&
3034 if (!
SI.hasNoNaNs() &&
3052 Instruction *NewFNeg = UnaryOperator::CreateFNeg(Fabs);
3061 for (
bool Swap : {
false,
true}) {
3077 if (Swap == TrueIfSigned && !CondVal->
hasOneUse() && !
TrueVal->hasOneUse())
3083 if (Swap != TrueIfSigned)
3088 return ChangedFMF ? &
SI :
nullptr;
3106foldRoundUpIntegerWithPow2Alignment(
SelectInst &SI,
3110 Value *XBiasedHighBits =
SI.getFalseValue();
3123 const APInt *LowBitMaskCst;
3128 const APInt *BiasCst, *HighBitMaskCst;
3129 if (!
match(XBiasedHighBits,
3132 !
match(XBiasedHighBits,
3137 if (!LowBitMaskCst->
isMask())
3140 APInt InvertedLowBitMaskCst = ~*LowBitMaskCst;
3141 if (InvertedLowBitMaskCst != *HighBitMaskCst)
3144 APInt AlignmentCst = *LowBitMaskCst + 1;
3146 if (*BiasCst != AlignmentCst && *BiasCst != *LowBitMaskCst)
3151 if (*BiasCst == *LowBitMaskCst &&
impliesPoison(XBiasedHighBits,
X))
3152 return XBiasedHighBits;
3157 Type *Ty =
X->getType();
3158 Value *XOffset = Builder.
CreateAdd(
X, ConstantInt::get(Ty, *LowBitMaskCst),
3159 X->getName() +
".biased");
3160 Value *
R = Builder.
CreateAnd(XOffset, ConstantInt::get(Ty, *HighBitMaskCst));
3166struct DecomposedSelect {
3178foldSelectOfSymmetricSelect(
SelectInst &OuterSelVal,
3181 Value *OuterCond, *InnerCond, *InnerTrueVal, *InnerFalseVal;
3209 DecomposedSelect OuterSel;
3216 std::swap(OuterSel.TrueVal, OuterSel.FalseVal);
3224 Value *InnerSelVal = IsAndVariant ? OuterSel.FalseVal : OuterSel.TrueVal;
3228 [](
Value *V) {
return V->hasOneUse(); }))
3232 DecomposedSelect InnerSel;
3233 if (!
match(InnerSelVal,
3240 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
3242 Value *AltCond =
nullptr;
3243 auto matchOuterCond = [OuterSel, IsAndVariant, &AltCond](
auto m_InnerCond) {
3248 return IsAndVariant ?
match(OuterSel.Cond,
3258 if (matchOuterCond(
m_Specific(InnerSel.Cond))) {
3263 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
3264 InnerSel.Cond = NotInnerCond;
3269 AltCond, IsAndVariant ? OuterSel.TrueVal : InnerSel.FalseVal,
3270 IsAndVariant ? InnerSel.TrueVal : OuterSel.FalseVal);
3273 IsAndVariant ? SelInner : InnerSel.TrueVal,
3274 !IsAndVariant ? SelInner : InnerSel.FalseVal);
3280static bool impliesPoisonOrCond(
const Value *ValAssumedPoison,
const Value *V,
3287 if (
auto *ICmp = dyn_cast<ICmpInst>(ValAssumedPoison)) {
3292 if (ICmp->hasSameSign() &&
3311 Value *CondVal =
SI.getCondition();
3314 Type *SelType =
SI.getType();
3331 if (impliesPoisonOrCond(FalseVal, CondVal,
false)) {
3333 return BinaryOperator::CreateOr(CondVal, FalseVal);
3337 impliesPoisonOrCond(FalseVal,
B,
false)) {
3347 bool CondLogicAnd = isa<SelectInst>(CondVal);
3348 bool FalseLogicAnd = isa<SelectInst>(FalseVal);
3349 auto AndFactorization = [&](
Value *Common,
Value *InnerCond,
3355 if (FalseLogicAnd || (CondLogicAnd && Common ==
A))
3358 return BinaryOperator::CreateAnd(Common, InnerSel);
3362 return AndFactorization(
A,
B,
D);
3364 return AndFactorization(
A,
B,
C);
3366 return AndFactorization(
B,
A,
D);
3368 return AndFactorization(
B,
A,
C, CondLogicAnd && FalseLogicAnd);
3373 if (impliesPoisonOrCond(TrueVal, CondVal,
true)) {
3375 return BinaryOperator::CreateAnd(CondVal, TrueVal);
3379 impliesPoisonOrCond(TrueVal,
B,
true)) {
3389 bool CondLogicOr = isa<SelectInst>(CondVal);
3390 bool TrueLogicOr = isa<SelectInst>(TrueVal);
3391 auto OrFactorization = [&](
Value *Common,
Value *InnerCond,
3397 if (TrueLogicOr || (CondLogicOr && Common ==
A))
3400 return BinaryOperator::CreateOr(Common, InnerSel);
3404 return OrFactorization(
A,
B,
D);
3406 return OrFactorization(
A,
B,
C);
3408 return OrFactorization(
B,
A,
D);
3410 return OrFactorization(
B,
A,
C, CondLogicOr && TrueLogicOr);
3453 return BinaryOperator::CreateXor(
A,
B);
3487 auto *FI =
new FreezeInst(*
Y, (*Y)->getName() +
".fr");
3493 if (
auto *V = foldBooleanAndOr(CondVal, Op1, SI, IsAnd,
3504 if (Res && *Res ==
false)
3510 if (Res && *Res ==
false)
3519 if (Res && *Res ==
true)
3525 if (Res && *Res ==
true)
3538 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3539 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3540 bool MayNeedFreeze = SelCond && SelFVal &&
3541 match(SelFVal->getTrueValue(),
3554 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3555 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3556 bool MayNeedFreeze = SelCond && SelFVal &&
3557 match(SelCond->getTrueValue(),
3573 bool &ShouldDropNoWrap) {
3596 ShouldDropNoWrap =
false;
3602 auto MatchForward = [&](
Value *CommonAncestor) {
3603 const APInt *
C =
nullptr;
3604 if (CtlzOp == CommonAncestor)
3607 ShouldDropNoWrap =
true;
3612 ShouldDropNoWrap =
true;
3623 const APInt *
C =
nullptr;
3624 Value *CommonAncestor;
3625 if (MatchForward(Cond0)) {
3629 if (!MatchForward(CommonAncestor))
3667 Type *SelType =
SI.getType();
3674 Value *Cond0, *Ctlz, *CtlzOp;
3683 bool ShouldDropNoWrap;
3690 !isSafeToRemoveBitCeilSelect(Pred, Cond0, Cond1, CtlzOp,
BitWidth,
3694 if (ShouldDropNoWrap) {
3695 cast<Instruction>(CtlzOp)->setHasNoUnsignedWrap(
false);
3696 cast<Instruction>(CtlzOp)->setHasNoSignedWrap(
false);
3705 cast<Instruction>(Ctlz)->dropPoisonGeneratingAnnotations();
3707 cast<Instruction>(Ctlz)->setOperand(1, Builder.
getFalse());
3724 Value *TV =
SI.getTrueValue();
3725 Value *FV =
SI.getFalseValue();
3737 if (!isa<Constant>(TV)) {
3738 if (!isa<Constant>(FV))
3745 if (
Constant *
C = dyn_cast<Constant>(RHS)) {
3746 auto FlippedPredAndConst =
3748 if (!FlippedPredAndConst)
3750 Pred = FlippedPredAndConst->first;
3751 RHS = FlippedPredAndConst->second;
3768 bool Replace =
false;
3790 const APInt *InnerTV, *InnerFV;
3796 FalseBranchSelectPredicate =
3801 if (!InnerTV->
isOne()) {
3813 Intrinsic::ID IID = IsSigned ? Intrinsic::scmp : Intrinsic::ucmp;
3835 FastMathFlags FMF = cast<FPMathOperator>(TrueVal)->getFastMathFlags();
3857 if (
auto *
I = dyn_cast<Instruction>(V)) {
3858 if (isa<PHINode>(
I)) {
3864 return Op->getType()->isIntOrIntVectorTy() &&
3865 hasAffectedValue(Op, Affected, Depth + 1);
3878 auto *SIFOp = dyn_cast<FPMathOperator>(&SI);
3879 if (!SIFOp || !SIFOp->hasNoSignedZeros() || !SIFOp->hasNoNaNs())
3882 auto TryFoldIntoAddConstant =
3894 Swapped ?
X :
Z,
"", &
SI);
3905 cast<Instruction>(NewFAdd)->setFastMathFlags(NewFMF);
3906 cast<Instruction>(NewSelect)->setFastMathFlags(NewFMF);
3925 return TryFoldIntoAddConstant(Pred,
X, Z,
FAdd,
C,
false);
3929 return TryFoldIntoAddConstant(Pred,
X, Z,
FAdd,
C,
true);
3945 bool CreateAnd =
false;
3947 Value *CmpLHS, *CmpRHS;
3955 const APInt *AndRHS;
3962 AndMask = Res->Mask;
3974 }
else if (
auto *Trunc = dyn_cast<TruncInst>(CondVal)) {
3975 V = Trunc->getOperand(0);
3976 AndMask =
APInt(
V->getType()->getScalarSizeInBits(), 1);
3978 CreateAnd = !Trunc->hasNoUnsignedWrap();
3987 CreateAnd, Builder))
3991 CreateAnd, Builder))
3998 Value *CondVal =
SI.getCondition();
4001 Type *SelType =
SI.getType();
4010 if (
Instruction *
I = canonicalizeScalarSelectOfVecs(SI, *
this))
4052 return new ZExtInst(CondVal, SelType);
4056 return new SExtInst(CondVal, SelType);
4061 return new ZExtInst(NotCond, SelType);
4067 return new SExtInst(NotCond, SelType);
4071 auto *SIFPOp = dyn_cast<FPMathOperator>(&SI);
4073 if (
auto *FCmp = dyn_cast<FCmpInst>(CondVal)) {
4075 Value *Cmp0 = FCmp->getOperand(0), *Cmp1 = FCmp->getOperand(1);
4077 if ((Cmp0 == TrueVal && Cmp1 == FalseVal) ||
4078 (Cmp0 == FalseVal && Cmp1 == TrueVal)) {
4087 FCmp->getName() +
".inv");
4090 if (FCmp->hasNoNaNs())
4092 if (FCmp->hasNoInfs())
4114 Value *MatchCmp0 =
nullptr;
4115 Value *MatchCmp1 =
nullptr;
4127 if (Cmp0 == MatchCmp0 &&
4128 matchFMulByZeroIfResultEqZero(*
this, Cmp0, Cmp1, MatchCmp1, MatchCmp0,
4129 SI, SIFPOp->hasNoSignedZeros()))
4137 auto *FCmp = dyn_cast<FCmpInst>(CondVal);
4141 if (SIFPOp->hasNoNaNs() &&
4142 (SIFPOp->hasNoSignedZeros() ||
4143 (SIFPOp->hasOneUse() &&
4149 if (
auto *BinIntrInst = dyn_cast<Instruction>(BinIntr)) {
4150 BinIntrInst->setHasNoNaNs(FCmp->hasNoNaNs());
4151 BinIntrInst->setHasNoInfs(FCmp->hasNoInfs());
4159 if (
auto *BinIntrInst = dyn_cast<Instruction>(BinIntr)) {
4160 BinIntrInst->setHasNoNaNs(FCmp->hasNoNaNs());
4161 BinIntrInst->setHasNoInfs(FCmp->hasNoInfs());
4169 if (
Instruction *Fabs = foldSelectWithFCmpToFabs(SI, *
this))
4173 if (
CmpInst *CI = dyn_cast<CmpInst>(CondVal))
4177 if (
ICmpInst *ICI = dyn_cast<ICmpInst>(CondVal))
4181 if (
Value *V = foldSelectBitTest(SI, CondVal, TrueVal, FalseVal,
Builder,
SQ))
4194 auto *TI = dyn_cast<Instruction>(TrueVal);
4195 auto *FI = dyn_cast<Instruction>(FalseVal);
4196 if (TI && FI && TI->getOpcode() == FI->
getOpcode())
4215 if (isa<VectorType>(CondVal->
getType()) && !isa<VectorType>(
Idx->getType()))
4227 if (
auto *TrueGep = dyn_cast<GetElementPtrInst>(TrueVal))
4228 if (
auto *NewGep = SelectGepWithBase(TrueGep, FalseVal,
false))
4230 if (
auto *FalseGep = dyn_cast<GetElementPtrInst>(FalseVal))
4231 if (
auto *NewGep = SelectGepWithBase(FalseGep, TrueVal,
true))
4247 RHS2, SI, SPF, RHS))
4251 RHS2, SI, SPF, LHS))
4260 bool IsCastNeeded =
LHS->
getType() != SelType;
4261 Value *CmpLHS = cast<CmpInst>(CondVal)->getOperand(0);
4262 Value *CmpRHS = cast<CmpInst>(CondVal)->getOperand(1);
4265 ((CmpLHS != LHS && CmpLHS != RHS) ||
4266 (CmpRHS != LHS && CmpRHS != RHS)))) {
4274 cast<Instruction>(
SI.getCondition()));
4287 if (
auto *PN = dyn_cast<PHINode>(
SI.getCondition()))
4291 if (
SelectInst *TrueSI = dyn_cast<SelectInst>(TrueVal)) {
4292 if (TrueSI->getCondition()->getType() == CondVal->
getType()) {
4295 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(
4296 *TrueSI, CondVal,
true,
DL))
4303 if (TrueSI->getFalseValue() == FalseVal && TrueSI->hasOneUse()) {
4311 if (
SelectInst *FalseSI = dyn_cast<SelectInst>(FalseVal)) {
4312 if (FalseSI->getCondition()->getType() == CondVal->
getType()) {
4315 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(
4316 *FalseSI, CondVal,
false,
DL))
4320 if (FalseSI->getTrueValue() == TrueVal && FalseSI->hasOneUse()) {
4337 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(0))) {
4338 if (TrueBOSI->getCondition() == CondVal) {
4344 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(1))) {
4345 if (TrueBOSI->getCondition() == CondVal) {
4356 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(0))) {
4357 if (FalseBOSI->getCondition() == CondVal) {
4363 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(1))) {
4364 if (FalseBOSI->getCondition() == CondVal) {
4377 SI.swapProfMetadata();
4402 if (
Value *V = foldSelectCmpXchg(SI))
4420 if (
Value *V = foldRoundUpIntegerWithPow2Alignment(SI,
Builder))
4433 auto *MaskedInst = cast<IntrinsicInst>(TrueVal);
4434 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
4435 MaskedInst->setArgOperand(3, FalseVal );
4450 bool CanMergeSelectIntoLoad =
false;
4454 if (CanMergeSelectIntoLoad) {
4455 auto *MaskedInst = cast<IntrinsicInst>(FalseVal);
4456 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
4457 MaskedInst->setArgOperand(3, TrueVal );
4489 auto FoldSelectWithAndOrCond = [&](
bool IsAnd,
Value *
A,
4497 if (
ICmpInst *Cmp = dyn_cast<ICmpInst>(
B))
4498 if (
Value *V = canonicalizeSPF(*Cmp, TrueVal, FalseVal, *
this))
4500 IsAnd ? FalseVal : V);
4508 if (
Instruction *
I = FoldSelectWithAndOrCond(
true, LHS, RHS))
4510 if (
Instruction *
I = FoldSelectWithAndOrCond(
true, RHS, LHS))
4513 if (
Instruction *
I = FoldSelectWithAndOrCond(
false, LHS, RHS))
4515 if (
Instruction *
I = FoldSelectWithAndOrCond(
false, RHS, LHS))
4521 if (
Instruction *
I = FoldSelectWithAndOrCond(
true, LHS, RHS))
4524 if (
Instruction *
I = FoldSelectWithAndOrCond(
false, LHS, RHS))
4531 return BinaryOperator::CreateXor(CondVal, FalseVal);
4536 (!isa<Constant>(TrueVal) || !isa<Constant>(FalseVal))) {
4540 CC.AffectedValues.insert(V);
4543 if (!CC.AffectedValues.empty()) {
4544 if (!isa<Constant>(TrueVal) &&
4545 hasAffectedValue(TrueVal, CC.AffectedValues, 0)) {
4553 if (!isa<Constant>(FalseVal) &&
4554 hasAffectedValue(FalseVal, CC.AffectedValues, 0)) {
4569 if (TrueVal == Trunc)
4571 if (FalseVal == Trunc)
4575 if (TrueVal == Trunc)
4578 if (FalseVal == Trunc)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 * foldSelectICmpMinMax(const ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder, const SimplifyQuery &SQ)
Try to fold a select to a min/max intrinsic.
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 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 * foldSelectZeroOrFixedOp(SelectInst &SI, InstCombinerImpl &IC)
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 * foldSelectICmpAnd(SelectInst &Sel, Value *CondVal, Value *TrueVal, Value *FalseVal, Value *V, const APInt &AndMask, bool CreateAnd, 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...
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 * 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 * foldSelectICmpAndBinOp(Value *CondVal, Value *TrueVal, Value *FalseVal, Value *V, const APInt &AndMask, bool CreateAnd, 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,...
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
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.
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 LLVM_ABI BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
static LLVM_ABI 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 LLVM_ABI 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 isNonStrictPredicate() const
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 LLVM_ABI 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
static LLVM_ABI bool isOrdered(Predicate predicate)
Determine if the predicate is an ordered operation.
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 LLVM_ABI std::optional< CmpPredicate > getMatching(CmpPredicate A, CmpPredicate B)
Compares two CmpPredicates taking samesign into account and returns the canonicalized CmpPredicate if...
static LLVM_ABI Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)
Return the identity constant for a binary opcode.
static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
This class represents a range of values.
LLVM_ABI ConstantRange add(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an addition of a value in this ran...
LLVM_ABI 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 LLVM_ABI ConstantRange intrinsic(Intrinsic::ID IntrinsicID, ArrayRef< ConstantRange > Ops)
Compute range of intrinsic result for the given operand ranges.
static LLVM_ABI 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...
LLVM_ABI ConstantRange binaryNot() const
Return a new range representing the possible values resulting from a binary-xor of a value in this ra...
LLVM_ABI 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...
LLVM_ABI 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 LLVM_ABI Constant * mergeUndefsWith(Constant *C, Constant *Other)
Merges undefs of a Constant with another Constant, along with the undefs already present.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
LLVM_ABI bool isOneValue() const
Returns true if the value is one.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
LLVM_ABI 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.
LLVM_ABI 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)
void setNoNaNs(bool B=true)
void setNoInfs(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
LLVM_ABI 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.
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)
LLVM_ABI Value * CreateSelectFMF(Value *C, Value *True, Value *False, FMFSource FMFSource, const Twine &Name="", Instruction *MDFrom=nullptr)
LLVM_ABI Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")
Return a vector value that contains.
ConstantInt * getTrue()
Get the constant value for i1 true.
Value * CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI 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)
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="", MDNode *FPMathTag=nullptr, FMFSource FMFSource={})
Value * CreateFCmpFMF(CmpInst::Predicate P, Value *LHS, Value *RHS, FMFSource FMFSource, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
LLVM_ABI Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 2 operands which is mangled on the first type.
LLVM_ABI CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
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.
LLVM_ABI CallInst * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 1 operand which is mangled on its type.
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 * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
ConstantInt * getFalse()
Get the constant value for i1 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 * 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)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
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.
Value * foldSelectWithConstOpToBinOp(ICmpInst *Cmp, Value *TrueVal, Value *FalseVal)
Instruction * visitSelectInst(SelectInst &SI)
Instruction * foldSelectOfBools(SelectInst &SI)
Instruction * foldSelectExtConst(SelectInst &Sel)
The core instruction combiner logic.
const DataLayout & getDataLayout() const
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)
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 computeKnownBits(const Value *V, KnownBits &Known, const Instruction *CxtI, unsigned Depth=0) const
void addToWorklist(Instruction *I)
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
const SimplifyQuery & getSimplifyQuery() const
static Constant * AddOne(Constant *C)
Add one to a Constant.
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, const Instruction *CxtI=nullptr, unsigned Depth=0)
void add(Instruction *I)
Add instruction to the worklist.
void push(Instruction *I)
Push the instruction onto the worklist stack.
LLVM_ABI bool hasNoNaNs() const LLVM_READONLY
Determine whether the no-NaNs flag is set.
LLVM_ABI bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
LLVM_ABI bool hasNoInfs() const LLVM_READONLY
Determine whether the no-infs flag is set.
LLVM_ABI 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.
LLVM_ABI void setHasNoSignedZeros(bool B)
Set or clear the no-signed-zeros flag on this instruction, which must be an operator which supports t...
LLVM_ABI bool hasNoSignedZeros() const LLVM_READONLY
Determine whether the no-signed-zeros flag is set.
LLVM_ABI bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
LLVM_ABI void copyIRFlags(const Value *V, bool IncludeWrapFlags=true)
Convenience method to copy supported exact, fast-math, and (optionally) wrapping flags from V to this...
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
LLVM_ABI void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction.
LLVM_ABI void setHasNoNaNs(bool B)
Set or clear the no-nans flag on this instruction, which must be an operator which supports this flag...
LLVM_ABI bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
LLVM_ABI void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
LLVM_ABI void swapProfMetadata()
If the instruction has "branch_weights" MD_prof metadata and the MDNode has three operands (including...
LLVM_ABI void setHasNoInfs(bool B)
Set or clear the no-infs flag on this instruction, which must be an operator which supports this flag...
LLVM_ABI 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.
LLVM_ABI 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 LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
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.
LLVM_ABI 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.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI 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.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
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.
cst_pred_ty< is_sign_mask > m_SignMask()
Match an integer or vector with only the sign bit(s) set.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWAdd(const LHS &L, const RHS &R)
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)
BinOpPred_match< LHS, RHS, is_idiv_op > m_IDiv(const LHS &L, const RHS &R)
Matches integer division operations.
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()...
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.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
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.
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)
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
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.
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_FShl(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
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.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap > m_NSWAdd(const LHS &L, const RHS &R)
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)
BinOpPred_match< LHS, RHS, is_irem_op > m_IRem(const LHS &L, const RHS &R)
Matches integer remainder operations.
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)
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_FShr(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
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< 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.
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.
LLVM_ABI Constant * ConstantFoldBinaryIntrinsic(Intrinsic::ID ID, Constant *LHS, Constant *RHS, Type *Ty, Instruction *FMFSource)
LLVM_ABI 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.
LLVM_ABI 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.
LLVM_ABI CmpInst::Predicate getMinMaxPred(SelectPatternFlavor SPF, bool Ordered=false)
Return the canonical comparison predicate for the specified minimum/maximum flavor.
LLVM_ABI bool canIgnoreSignBitOfZero(const Use &U)
Return true if the sign bit of the FP value can be ignored by the user when the value is zero.
LLVM_ABI 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.
LLVM_ABI 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.
LLVM_ABI bool impliesPoison(const Value *ValAssumedPoison, const Value *V)
Return true if V is poison given that ValAssumedPoison is already poison.
LLVM_ABI SelectPatternResult getSelectPattern(CmpInst::Predicate Pred, SelectPatternNaNBehavior NaNBehavior=SPNB_NA, bool Ordered=false)
Determine the pattern for predicate X Pred Y ? X : Y.
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
LLVM_ABI 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...
LLVM_ABI bool cannotBeNegativeZero(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if we can prove that the specified FP value is never equal to -0.0.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
LLVM_ABI Value * simplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an And, fold the result or return null.
LLVM_ABI bool isKnownInversion(const Value *X, const Value *Y)
Return true iff:
LLVM_ABI bool isNotCrossLaneOperation(const Instruction *I)
Return true if the instruction doesn't potentially cross vector lanes.
LLVM_ABI Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
constexpr int PoisonMaskElem
LLVM_ABI Intrinsic::ID getMinMaxIntrinsic(SelectPatternFlavor SPF)
Convert given SPF to equivalent min/max intrinsic.
LLVM_ABI SelectPatternResult matchDecomposedSelectPattern(CmpInst *CmpI, Value *TrueVal, Value *FalseVal, Value *&LHS, Value *&RHS, FastMathFlags FMF=FastMathFlags(), 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...
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
DWARFExpression::Operation Op
bool isSafeToSpeculativelyExecuteWithVariableReplaced(const Instruction *I, bool IgnoreUBImplyingAttrs=true)
Don't use information from its non-constant operands.
constexpr unsigned BitWidth
LLVM_ABI 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.
LLVM_ABI bool isKnownNeverNaN(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...
auto predecessors(const MachineBasicBlock *BB)
LLVM_ABI std::optional< std::pair< CmpPredicate, Constant * > > getFlippedStrictnessPredicateAndConstant(CmpPredicate Pred, Constant *C)
Convert an integer comparison with a constant RHS into an equivalent form with the strictness flipped...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
LLVM_ABI 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,...
LLVM_ABI Value * simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, const SimplifyQuery &Q)
Given operands for a SelectInst, fold the result or return null.
LLVM_ABI 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.
std::optional< DecomposedBitTest > decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate Pred, bool LookThroughTrunc=true, bool AllowNonZeroC=false, bool DecomposeAnd=false)
Decompose an icmp into the form ((X & Mask) pred C) if possible.
LLVM_ABI bool canIgnoreSignBitOfNaN(const Use &U)
Return true if the sign bit of the FP value can be ignored by the user when the value is NaN.
LLVM_ABI 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.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
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