50#define DEBUG_TYPE "instcombine"
111 if (!FPO->hasNoSignedZeros() &&
136 const APInt *SelTC, *SelFC;
145 const APInt &TC = *SelTC;
146 const APInt &FC = *SelFC;
147 if (!TC.
isZero() && !FC.isZero()) {
159 Constant *TCC = ConstantInt::get(SelType, TC);
160 Constant *FCC = ConstantInt::get(SelType, FC);
161 Constant *MaskC = ConstantInt::get(SelType, AndMask);
162 for (
auto Opc : {Instruction::Or, Instruction::Xor, Instruction::Add,
167 V = Builder.CreateAnd(V, MaskC);
168 return Builder.CreateBinOp(
Opc, TCC, V);
182 unsigned ValZeros = ValC.
logBase2();
183 unsigned AndZeros = AndMask.
logBase2();
184 bool ShouldNotVal = !TC.
isZero();
185 bool NeedShift = ValZeros != AndZeros;
192 if (CreateAnd + ShouldNotVal + NeedShift + NeedZExtTrunc >
198 V = Builder.CreateAnd(V, ConstantInt::get(V->getType(), AndMask));
202 if (ValZeros > AndZeros) {
203 V = Builder.CreateZExtOrTrunc(V, SelType);
204 V = Builder.CreateShl(V, ValZeros - AndZeros);
205 }
else if (ValZeros < AndZeros) {
206 V = Builder.CreateLShr(V, AndZeros - ValZeros);
207 V = Builder.CreateZExtOrTrunc(V, SelType);
209 V = Builder.CreateZExtOrTrunc(V, SelType);
215 V = Builder.CreateXor(V, ValC);
231 switch (
I->getOpcode()) {
232 case Instruction::Add:
233 case Instruction::FAdd:
234 case Instruction::Mul:
235 case Instruction::FMul:
236 case Instruction::And:
237 case Instruction::Or:
238 case Instruction::Xor:
240 case Instruction::Sub:
241 case Instruction::FSub:
242 case Instruction::FDiv:
243 case Instruction::Shl:
244 case Instruction::LShr:
245 case Instruction::AShr:
277 CondVTy->getElementCount() !=
289 if (TI->
getOpcode() != Instruction::BitCast &&
302 SI.getName() +
".v", &
SI);
307 Value *OtherOpT, *OtherOpF;
310 bool Swapped =
false) ->
Value * {
311 assert(!(Commute && Swapped) &&
312 "Commute and Swapped can't set at the same time");
317 MatchIsOpZero =
true;
322 MatchIsOpZero =
false;
327 if (!Commute && !Swapped)
336 MatchIsOpZero =
true;
341 MatchIsOpZero =
false;
355 FMF |=
SI.getFastMathFlags();
359 NewSelI->setFastMathFlags(FMF);
360 Instruction *NewFNeg = UnaryOperator::CreateFNeg(NewSel);
371 if (
TII && FII &&
TII->getIntrinsicID() == FII->getIntrinsicID()) {
373 if (
Value *MatchOp = getCommonOp(TI, FI,
true)) {
375 Builder.CreateSelect(
Cond, OtherOpT, OtherOpF,
"minmaxop", &
SI);
385 if (
TII->getIntrinsicID() == Intrinsic::ldexp) {
386 Value *LdexpVal0 =
TII->getArgOperand(0);
387 Value *LdexpExp0 =
TII->getArgOperand(1);
388 Value *LdexpVal1 = FII->getArgOperand(0);
389 Value *LdexpExp1 = FII->getArgOperand(1);
400 TII->getType(), Intrinsic::ldexp, {SelectVal, SelectExp});
407 auto CreateCmpSel = [&](std::optional<CmpPredicate>
P,
416 SI.getName() +
".v", &
SI);
470 if (BO->getOpcode() == Instruction::SDiv ||
471 BO->getOpcode() == Instruction::SRem || MatchIsOpZero)
477 SI.getName() +
".v", &
SI);
478 Value *Op0 = MatchIsOpZero ? MatchOp : NewSI;
479 Value *Op1 = MatchIsOpZero ? NewSI : MatchOp;
488 Type *ElementType = TGEP->getSourceElementType();
490 ElementType, Op0, Op1, TGEP->getNoWrapFlags() & FGEP->getNoWrapFlags());
516 unsigned OpToFold = 0;
517 if ((SFO & 1) && FalseVal == TVI->getOperand(0))
519 else if ((SFO & 2) && FalseVal == TVI->getOperand(1))
527 FMF = FPO->getFastMathFlags();
529 TVI->getOpcode(), TVI->getType(),
true, FMF.
noSignedZeros());
530 Value *OOp = TVI->getOperand(2 - OpToFold);
536 (!OOpIsAPInt || !
isSelect01(
C->getUniqueInteger(), *OOpC)))
549 Value *NewSel =
Builder.CreateSelect(
SI.getCondition(), Swapped ?
C : OOp,
550 Swapped ? OOp :
C,
"", &
SI);
561 bool CanInferFiniteOperandsFromResult =
562 TVI->getOpcode() == Instruction::FAdd ||
563 TVI->getOpcode() == Instruction::FSub ||
564 TVI->getOpcode() == Instruction::FMul;
566 (CanInferFiniteOperandsFromResult &&
585 if (
Instruction *R = TryFoldSelectIntoOp(
SI, TrueVal, FalseVal,
false))
588 if (
Instruction *R = TryFoldSelectIntoOp(
SI, FalseVal, TrueVal,
true))
601 const Value *CmpLHS = Cmp->getOperand(0);
602 const Value *CmpRHS = Cmp->getOperand(1);
609 if (CmpRHS == TVal) {
622 return Builder.CreateBinaryIntrinsic(Intrinsic::smax, TVal, FVal);
628 return Builder.CreateBinaryIntrinsic(Intrinsic::smin, TVal, FVal);
634 return Builder.CreateBinaryIntrinsic(Intrinsic::umax, TVal, FVal);
644 return Builder.CreateBinaryIntrinsic(Intrinsic::umin, TVal, FVal);
661 if (!(Cmp->hasOneUse() && Cmp->getOperand(0)->hasOneUse() &&
693 Constant *One = ConstantInt::get(SelType, 1);
694 Value *MaskB = HasShift ? Builder.CreateShl(One, Z) : One;
695 Value *FullMask = Builder.CreateOr(
Y, MaskB);
696 Value *MaskedX = Builder.CreateAnd(
X, FullMask);
697 Value *ICmpNeZero = Builder.CreateIsNotNull(MaskedX);
698 return new ZExtInst(ICmpNeZero, SelType);
720 const APInt *C2, *C1;
734 FI->setHasNoSignedWrap(
false);
735 FI->setHasNoUnsignedWrap(
false);
773 return Builder.CreateAShr(
X,
Y, IC->
getName(), IsExact);
801 const APInt &AndMask,
bool CreateAnd,
804 if (!TrueVal->getType()->isIntOrIntVectorTy())
807 unsigned C1Log = AndMask.
logBase2();
828 if (IdentityC ==
nullptr || !IdentityC->isNullValue())
833 bool NeedShift = C1Log != C2Log;
834 bool NeedZExtTrunc =
Y->getType()->getScalarSizeInBits() !=
835 V->getType()->getScalarSizeInBits();
838 if ((NeedShift + NeedXor + NeedZExtTrunc + CreateAnd) >
844 V = Builder.CreateAnd(V, ConstantInt::get(V->getType(), AndMask));
848 V = Builder.CreateZExtOrTrunc(V,
Y->getType());
849 V = Builder.CreateShl(V, C2Log - C1Log);
850 }
else if (C1Log > C2Log) {
851 V = Builder.CreateLShr(V, C1Log - C2Log);
852 V = Builder.CreateZExtOrTrunc(V,
Y->getType());
854 V = Builder.CreateZExtOrTrunc(V,
Y->getType());
857 V = Builder.CreateXor(V, *C2);
859 auto *Res = Builder.CreateBinOp(BinOp->
getOpcode(),
Y, V);
861 BO->copyIRFlags(BinOp);
880 Constant *OrC = ConstantInt::get(Ty, *
C);
881 Value *NewSel = Builder.CreateSelect(
Cond, Zero, OrC,
"masksel", &Sel);
882 return BinaryOperator::CreateOr(
T, NewSel);
889 Constant *OrC = ConstantInt::get(Ty, *
C);
890 Value *NewSel = Builder.CreateSelect(
Cond, OrC, Zero,
"masksel", &Sel);
891 return BinaryOperator::CreateOr(
F, NewSel);
912 auto *CondVal =
SI.getCondition();
913 auto *TrueVal =
SI.getTrueValue();
914 auto *FalseVal =
SI.getFalseValue();
964 FalseValI->getOperand(0) ==
Y
966 : (FalseValI->getOperand(1) ==
Y ? 1 : 2),
975 const Value *TrueVal,
976 const Value *FalseVal,
996 return Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat,
A,
997 ConstantInt::get(
A->getType(), 1));
1011 "Unexpected isUnsigned predicate!");
1017 bool IsNegative =
false;
1030 if (IsNegative && !TrueVal->hasOneUse() && !ICI->
hasOneUse())
1035 Value *Result = Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat,
A,
B);
1037 Result = Builder.CreateNeg(Result);
1046 Value *Cmp0 = Cmp->getOperand(0);
1047 Value *Cmp1 = Cmp->getOperand(1);
1067 return Builder.CreateBinaryIntrinsic(
1068 Intrinsic::uadd_sat, Cmp0, ConstantInt::get(Cmp0->
getType(), 1));
1078 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp0,
1079 ConstantInt::get(Cmp0->
getType(), *
C));
1088 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp0,
1089 ConstantInt::get(Cmp0->
getType(), *
C));
1098 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp0,
1099 ConstantInt::get(Cmp0->
getType(), *
C));
1117 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat,
X,
Y);
1127 return Builder.CreateBinaryIntrinsic(
1137 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp1,
Y);
1147 Value *Cmp0 = Cmp->getOperand(0);
1148 Value *Cmp1 = Cmp->getOperand(1);
1167 return Builder.CreateBinaryIntrinsic(
1168 Intrinsic::sadd_sat, Cmp0, ConstantInt::get(Cmp0->
getType(), 1));
1186 Pred = Flipped->first;
1187 Cmp1 = Flipped->second;
1195 return Builder.CreateBinaryIntrinsic(
1196 Intrinsic::sadd_sat, Cmp0, ConstantInt::get(Cmp0->
getType(), *
C));
1212 return Builder.CreateBinaryIntrinsic(Intrinsic::sadd_sat,
X, Cmp1);
1220 if (!Cmp->hasOneUse())
1242 Value *
A = Cmp->getOperand(0);
1243 Value *
B = Cmp->getOperand(1);
1256 (TI->hasNoSignedWrap() || TI->hasNoUnsignedWrap()) &&
1257 (FI->hasNoSignedWrap() || FI->hasNoUnsignedWrap())) {
1264 TI->setHasNoUnsignedWrap(
false);
1265 if (!TI->hasNoSignedWrap())
1266 TI->setHasNoSignedWrap(TI->hasOneUse());
1267 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, TI, Builder.getTrue());
1274 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, TI,
1275 Builder.getFalse());
1282 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, FI,
1283 Builder.getFalse());
1290 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, FI,
1291 Builder.getFalse());
1298 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, TI,
1299 Builder.getFalse());
1326 if (!
match(FalseVal,
1342 II->getModule(), Intrinsic::cttz,
II->getType());
1398 unsigned SizeOfInBits =
Count->getType()->getScalarSizeInBits();
1401 II->dropPoisonGeneratingAnnotations();
1413 II->dropUBImplyingAttrsAndMetadata();
1424 if (!
TrueVal->getType()->isIntOrIntVectorTy())
1464 if (!
I || !
I->hasOneUse() ||
1473 for (Use &U :
I->operands()) {
1506 bool Swapped =
false;
1507 if (
Cmp.isEquivalence(
true)) {
1510 }
else if (!
Cmp.isEquivalence()) {
1514 Value *CmpLHS =
Cmp.getOperand(0), *CmpRHS =
Cmp.getOperand(1);
1515 auto ReplaceOldOpWithNewOp = [&](
Value *OldOp,
1516 Value *NewOp) -> Instruction * {
1563 if (CanReplaceCmpLHSWithRHS) {
1564 if (Instruction *R = ReplaceOldOpWithNewOp(CmpLHS, CmpRHS))
1568 if (CanReplaceCmpRHSWithLHS) {
1569 if (Instruction *R = ReplaceOldOpWithNewOp(CmpRHS, CmpLHS))
1586 if ((CanReplaceCmpLHSWithRHS &&
1589 &DropFlags) == TrueVal) ||
1590 (CanReplaceCmpRHSWithLHS &&
1593 &DropFlags) == TrueVal)) {
1594 for (Instruction *
I : DropFlags) {
1595 I->dropPoisonGeneratingAnnotations();
1716 if (Cmp00->
getType() !=
X->getType() &&
X->hasOneUse())
1724 else if (!
match(Cmp00,
1732 Value *ReplacementLow, *ReplacementHigh;
1769 std::swap(ReplacementLow, ReplacementHigh);
1775 "Unexpected predicate type.");
1783 "Unexpected predicate type.");
1785 std::swap(ThresholdLowIncl, ThresholdHighExcl);
1801 if (
X->getType() != Sel0.
getType()) {
1811 assert(ReplacementLow && ReplacementHigh &&
1812 "Constant folding of ImmConstant cannot fail");
1818 Value *MaybeReplacedLow =
1824 ShouldReplaceHigh, ReplacementHigh, MaybeReplacedLow);
1868 Value *SelVal0, *SelVal1;
1877 auto MatchesSelectValue = [SelVal0, SelVal1](
Constant *
C) {
1878 return C->isElementWiseEqual(SelVal0) ||
C->isElementWiseEqual(SelVal1);
1882 if (MatchesSelectValue(C0))
1887 if (!FlippedStrictness)
1891 if (!MatchesSelectValue(FlippedStrictness->second))
1900 Cmp.getName() +
".inv");
1911 if (!
Cmp->hasOneUse())
1941 Value *TVal =
SI.getTrueValue();
1942 Value *FVal =
SI.getFalseValue();
1976 Op->dropPoisonGeneratingFlags();
1981 MMI && MMI->getLHS() == V &&
match(MMI->getRHS(),
m_APInt(OpC))) {
1983 {InvDomCR, ConstantRange(*OpC)});
1985 MMI->dropPoisonGeneratingAnnotations();
2048 foldSelectWithExtremeEqCond(CmpLHS, CmpRHS, TrueVal, FalseVal))
2080 Opcode = BOp->getOpcode();
2081 IsIntrinsic =
false;
2095 Opcode =
II->getIntrinsicID();
2103 const DataLayout &
DL =
Cmp->getDataLayout();
2112 if (C3 == FoldBinaryOpOrIntrinsic(C1, C2)) {
2115 }
else if (Flipped && C3 == FoldBinaryOpOrIntrinsic(Flipped->second, C2)) {
2117 RHS = Flipped->second;
2125 return Builder.CreateBinaryIntrinsic(Opcode, MinMax, C2);
2128 Value *BinOp =
Builder.CreateBinOp(BinOpc, MinMax, C2);
2133 if (BinOpc == Instruction::Add || BinOpc == Instruction::Sub ||
2134 BinOpc == Instruction::Mul) {
2137 willNotOverflow(BinOpc,
RHS, C2, *BinOpInst,
true))
2138 BinOpInst->setHasNoSignedWrap();
2140 willNotOverflow(BinOpc,
RHS, C2, *BinOpInst,
false))
2141 BinOpInst->setHasNoUnsignedWrap();
2159static Instruction *foldICmpUSubSatWithAndForMostSignificantBitCmp(
2165 const APInt *Constant1, *Constant2;
2183 auto *Ty =
A->getType();
2191 APInt AdjAP1 = *Constant1 - MostSignificantBit + 1;
2192 APInt AdjAP2 = *Constant2 - MostSignificantBit + 1;
2194 auto *Adj1 = ConstantInt::get(Ty, AdjAP1);
2195 auto *Adj2 = ConstantInt::get(Ty, AdjAP2);
2200 Constant *MSBConst = ConstantInt::get(Ty, MostSignificantBit);
2201 return BinaryOperator::CreateAnd(
Or, MSBConst);
2208 canonicalizeSPF(*ICI,
SI.getTrueValue(),
SI.getFalseValue(), *
this))
2211 if (
Value *V = foldSelectInstWithICmpConst(SI, ICI,
Builder))
2214 if (
Value *V = canonicalizeClampLike(SI, *ICI,
Builder, *
this))
2217 if (Instruction *NewSel =
2218 tryToReuseConstantFromSelectInComparison(SI, *ICI, *
this))
2220 if (Instruction *Folded =
2221 foldICmpUSubSatWithAndForMostSignificantBitCmp(SI, ICI,
Builder))
2232 if (Instruction *NewSel = foldSelectICmpEq(SI, ICI, *
this))
2242 InstCombiner::BuilderTy::InsertPointGuard Guard(
Builder);
2247 SI.swapProfMetadata();
2254 if (Instruction *V =
2261 if (Instruction *V = foldSelectCtlzToCttz(ICI, TrueVal, FalseVal,
Builder))
2264 if (Instruction *V = foldSelectZeroOrOnes(ICI, TrueVal, FalseVal,
Builder))
2270 if (
Value *V = foldSelectCttzCtlz(ICI, TrueVal, FalseVal, *
this))
2298 if (
C ==
A ||
C ==
B) {
2313 Value *CondVal =
SI.getCondition();
2318 if (!TI || !FI || !TI->hasOneUse() || !FI->hasOneUse())
2322 if ((TI->getOpcode() == Instruction::Sub &&
2323 FI->getOpcode() == Instruction::Add) ||
2324 (TI->getOpcode() == Instruction::FSub &&
2325 FI->getOpcode() == Instruction::FAdd)) {
2328 }
else if ((FI->getOpcode() == Instruction::Sub &&
2329 TI->getOpcode() == Instruction::Add) ||
2330 (FI->getOpcode() == Instruction::FSub &&
2331 TI->getOpcode() == Instruction::FAdd)) {
2337 Value *OtherAddOp =
nullptr;
2338 if (SubOp->getOperand(0) == AddOp->
getOperand(0)) {
2340 }
else if (SubOp->getOperand(0) == AddOp->
getOperand(1)) {
2348 if (
SI.getType()->isFPOrFPVectorTy()) {
2349 NegVal = Builder.
CreateFNeg(SubOp->getOperand(1));
2352 Flags &= SubOp->getFastMathFlags();
2353 NegInst->setFastMathFlags(Flags);
2356 NegVal = Builder.
CreateNeg(SubOp->getOperand(1));
2359 Value *NewTrueOp = OtherAddOp;
2360 Value *NewFalseOp = NegVal;
2364 SI.getName() +
".p", &
SI);
2366 if (
SI.getType()->isFPOrFPVectorTy()) {
2368 BinaryOperator::CreateFAdd(SubOp->getOperand(0), NewSel);
2371 Flags &= SubOp->getFastMathFlags();
2375 return BinaryOperator::CreateAdd(SubOp->getOperand(0), NewSel);
2388 Value *CondVal =
SI.getCondition();
2400 auto IsSignedSaturateLimit = [&](
Value *Limit,
bool IsAdd) {
2410 auto IsZeroOrOne = [](
const APInt &
C) {
return C.isZero() ||
C.isOne(); };
2427 IsMinMax(TrueVal, FalseVal))
2434 IsMinMax(FalseVal, TrueVal))
2440 IsMinMax(TrueVal, FalseVal))
2445 IsMinMax(FalseVal, TrueVal))
2450 IsMinMax(FalseVal, TrueVal))
2455 IsMinMax(TrueVal, FalseVal))
2463 if (
II->getIntrinsicID() == Intrinsic::uadd_with_overflow &&
2466 NewIntrinsicID = Intrinsic::uadd_sat;
2467 else if (
II->getIntrinsicID() == Intrinsic::usub_with_overflow &&
2470 NewIntrinsicID = Intrinsic::usub_sat;
2471 else if (
II->getIntrinsicID() == Intrinsic::sadd_with_overflow &&
2472 IsSignedSaturateLimit(TrueVal,
true))
2481 NewIntrinsicID = Intrinsic::sadd_sat;
2482 else if (
II->getIntrinsicID() == Intrinsic::ssub_with_overflow &&
2483 IsSignedSaturateLimit(TrueVal,
false))
2492 NewIntrinsicID = Intrinsic::ssub_sat;
2497 NewIntrinsicID,
SI.getType());
2513 if (ExtOpcode != Instruction::ZExt && ExtOpcode != Instruction::SExt)
2523 (!Cmp ||
Cmp->getOperand(0)->getType() != SmallType))
2547 Value *CondVal =
SI.getCondition();
2553 unsigned NumElts = CondValTy->getNumElements();
2555 Mask.reserve(NumElts);
2556 for (
unsigned i = 0; i != NumElts; ++i) {
2566 Mask.push_back(i + NumElts);
2619 if (TVal ==
A || TVal ==
B || FVal ==
A || FVal ==
B)
2636 if (TSrc ==
C && FSrc ==
D) {
2640 }
else if (TSrc ==
D && FSrc ==
C) {
2682 if (Extract->getIndices()[0] !=
I)
2691 if (
Select->getCondition() ==
SI.getCondition())
2692 if (
Select->getFalseValue() ==
SI.getTrueValue() ||
2693 Select->getTrueValue() ==
SI.getFalseValue())
2697 auto *CmpXchg = isExtractFromCmpXchg(
SI.getCondition(), 1);
2704 if (
auto *
X = isExtractFromCmpXchg(
SI.getTrueValue(), 0))
2705 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getFalseValue())
2706 return SI.getFalseValue();
2711 if (
auto *
X = isExtractFromCmpXchg(
SI.getFalseValue(), 0))
2712 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getTrueValue())
2713 return SI.getFalseValue();
2737 Value *SV0, *SV1, *SA0, *SA1;
2746 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2752 Or1->
getOpcode() == BinaryOperator::LShr &&
2753 "Illegal or(shift,shift) pair");
2768 bool IsFshl = (ShAmt == SA0);
2770 if ((IsFshl && TVal != SV0) || (!IsFshl && TVal != SV1))
2790 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
2812 assert(TC != FC &&
"Expected equal select arms to simplify");
2816 bool IsTrueIfSignSet;
2834 Value *MagArg = ConstantFP::get(SelType,
abs(*TC));
2853 I->copyIRFlags(&Sel);
2856 M, Intrinsic::vector_reverse,
V->getType());
2864 return createSelReverse(
C,
X,
Y);
2868 return createSelReverse(
C,
X, FVal);
2873 return createSelReverse(
C, TVal,
Y);
2880 unsigned NumElts = VecTy->getNumElements();
2881 APInt PoisonElts(NumElts, 0);
2899 return new ShuffleVectorInst(
X, NewSel, Mask);
2904 return new ShuffleVectorInst(NewSel,
Y, Mask);
2913 return new ShuffleVectorInst(
X, NewSel, Mask);
2918 return new ShuffleVectorInst(NewSel,
Y, Mask);
2930 auto *IDomNode = DT[BB]->getIDom();
2936 Value *IfTrue, *IfFalse;
2952 if (TrueSucc == FalseSucc)
2974 if (!DT.
dominates(Insn, Pred->getTerminator()))
2993 CandidateBlocks.
insert(
I->getParent());
2996 if (
auto *PN = foldSelectToPhiImpl(Sel, BB, DT, Builder))
3009 Value *CondVal =
SI.getCondition();
3014 Value *
Op, *RemRes, *Remainder;
3016 bool TrueIfSigned =
false;
3030 return BinaryOperator::CreateAnd(
Op,
Add);
3042 return FoldToBitwiseAnd(Remainder);
3051 return FoldToBitwiseAnd(ConstantInt::get(RemRes->
getType(), 2));
3061 Value *InnerCondVal =
SI.getCondition();
3062 Value *InnerTrueVal =
SI.getTrueValue();
3063 Value *InnerFalseVal =
SI.getFalseValue();
3065 "The type of inner condition must match with the outer.");
3067 return *Implied ? InnerTrueVal : InnerFalseVal;
3074 assert(
Op->getType()->isIntOrIntVectorTy(1) &&
3075 "Op must be either i1 or vector of i1.");
3076 if (
SI.getCondition()->getType() !=
Op->getType())
3078 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(SI,
Op, IsAnd,
DL))
3079 return createSelectInstWithUnknownProfile(
3089 Value *CondVal =
SI.getCondition();
3091 bool ChangedFMF =
false;
3092 for (
bool Swap : {
false,
true}) {
3130 if (FMF.
noNaNs() && !
SI.hasNoNaNs()) {
3131 SI.setHasNoNaNs(
true);
3134 if (FMF.
noInfs() && !
SI.hasNoInfs()) {
3135 SI.setHasNoInfs(
true);
3142 SI.setHasNoNaNs(
true);
3156 if (!
SI.hasNoSignedZeros() &&
3159 if (!
SI.hasNoNaNs() &&
3177 Instruction *NewFNeg = UnaryOperator::CreateFNeg(Fabs);
3186 for (
bool Swap : {
false,
true}) {
3202 if (Swap == TrueIfSigned && !CondVal->
hasOneUse() && !
TrueVal->hasOneUse())
3208 if (Swap != TrueIfSigned)
3213 return ChangedFMF ? &
SI :
nullptr;
3235 Value *XBiasedHighBits =
SI.getFalseValue();
3248 const APInt *LowBitMaskCst;
3253 const APInt *BiasCst, *HighBitMaskCst;
3254 if (!
match(XBiasedHighBits,
3257 !
match(XBiasedHighBits,
3262 if (!LowBitMaskCst->
isMask())
3265 APInt InvertedLowBitMaskCst = ~*LowBitMaskCst;
3266 if (InvertedLowBitMaskCst != *HighBitMaskCst)
3269 APInt AlignmentCst = *LowBitMaskCst + 1;
3271 if (*BiasCst != AlignmentCst && *BiasCst != *LowBitMaskCst)
3276 if (*BiasCst == *LowBitMaskCst &&
impliesPoison(XBiasedHighBits,
X))
3277 return XBiasedHighBits;
3282 Type *Ty =
X->getType();
3283 Value *XOffset = Builder.
CreateAdd(
X, ConstantInt::get(Ty, *LowBitMaskCst),
3284 X->getName() +
".biased");
3285 Value *
R = Builder.
CreateAnd(XOffset, ConstantInt::get(Ty, *HighBitMaskCst));
3291struct DecomposedSelect {
3303foldSelectOfSymmetricSelect(
SelectInst &OuterSelVal,
3306 Value *OuterCond, *InnerCond, *InnerTrueVal, *InnerFalseVal;
3334 DecomposedSelect OuterSel;
3341 std::swap(OuterSel.TrueVal, OuterSel.FalseVal);
3349 Value *InnerSelVal = IsAndVariant ? OuterSel.FalseVal : OuterSel.TrueVal;
3357 DecomposedSelect InnerSel;
3358 if (!
match(InnerSelVal,
3365 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
3367 Value *AltCond =
nullptr;
3368 auto matchOuterCond = [OuterSel, IsAndVariant, &AltCond](
auto m_InnerCond) {
3373 return IsAndVariant ?
match(OuterSel.Cond,
3383 if (matchOuterCond(
m_Specific(InnerSel.Cond))) {
3388 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
3389 InnerSel.Cond = NotInnerCond;
3394 AltCond, IsAndVariant ? OuterSel.TrueVal : InnerSel.FalseVal,
3395 IsAndVariant ? InnerSel.TrueVal : OuterSel.FalseVal);
3398 IsAndVariant ? SelInner : InnerSel.TrueVal,
3399 !IsAndVariant ? SelInner : InnerSel.FalseVal);
3405static bool impliesPoisonOrCond(
const Value *ValAssumedPoison,
const Value *V,
3417 if (ICmp->hasSameSign() &&
3436 Value *CondVal =
SI.getCondition();
3439 Type *SelType =
SI.getType();
3456 if (impliesPoisonOrCond(FalseVal, CondVal,
false)) {
3458 return BinaryOperator::CreateOr(CondVal, FalseVal);
3462 impliesPoisonOrCond(FalseVal,
B,
false)) {
3477 auto AndFactorization = [&](
Value *Common,
Value *InnerCond,
3479 bool SelFirst =
false) -> Instruction * {
3480 Value *InnerSel =
Builder.CreateSelect(InnerCond, One, InnerVal);
3483 if (FalseLogicAnd || (CondLogicAnd && Common ==
A))
3486 return BinaryOperator::CreateAnd(Common, InnerSel);
3490 return AndFactorization(
A,
B,
D);
3492 return AndFactorization(
A,
B,
C);
3494 return AndFactorization(
B,
A,
D);
3496 return AndFactorization(
B,
A,
C, CondLogicAnd && FalseLogicAnd);
3501 if (impliesPoisonOrCond(TrueVal, CondVal,
true)) {
3503 return BinaryOperator::CreateAnd(CondVal, TrueVal);
3507 impliesPoisonOrCond(TrueVal,
B,
true)) {
3522 auto OrFactorization = [&](
Value *Common,
Value *InnerCond,
3524 bool SelFirst =
false) -> Instruction * {
3525 Value *InnerSel =
Builder.CreateSelect(InnerCond, InnerVal, Zero);
3528 if (TrueLogicOr || (CondLogicOr && Common ==
A))
3531 return BinaryOperator::CreateOr(Common, InnerSel);
3535 return OrFactorization(
A,
B,
D);
3537 return OrFactorization(
A,
B,
C);
3539 return OrFactorization(
B,
A,
D);
3541 return OrFactorization(
B,
A,
C, CondLogicOr && TrueLogicOr);
3602 return BinaryOperator::CreateXor(
A,
B);
3620 Value *AndV =
Builder.CreateSelect(NotC, FalseVal, Zero);
3636 auto *FI =
new FreezeInst(*
Y, (*Y)->getName() +
".fr");
3642 if (
auto *V = foldBooleanAndOr(CondVal, Op1, SI, IsAnd,
3653 if (Res && *Res ==
false)
3659 if (Res && *Res ==
false)
3668 if (Res && *Res ==
true)
3674 if (Res && *Res ==
true)
3689 bool MayNeedFreeze = SelCond && SelFVal &&
3690 match(SelFVal->getTrueValue(),
3695 Value *C2 =
nullptr, *A2 =
nullptr, *B2 =
nullptr;
3699 }
else if (
match(FalseVal,
3706 return createSelectInstWithUnknownProfile(
C,
A,
B);
3720 bool MayNeedFreeze = SelCond && SelFVal &&
3721 match(SelCond->getTrueValue(),
3726 Value *C2 =
nullptr, *A2 =
nullptr, *B2 =
nullptr;
3736 return createSelectInstWithUnknownProfile(
C,
B,
A);
3751 bool &ShouldDropNoWrap) {
3774 ShouldDropNoWrap =
false;
3780 auto MatchForward = [&](
Value *CommonAncestor) {
3781 const APInt *
C =
nullptr;
3782 if (CtlzOp == CommonAncestor)
3785 ShouldDropNoWrap =
true;
3790 ShouldDropNoWrap =
true;
3801 const APInt *
C =
nullptr;
3802 Value *CommonAncestor;
3803 if (MatchForward(Cond0)) {
3807 if (!MatchForward(CommonAncestor))
3845 Type *SelType =
SI.getType();
3854 Value *Cond0, *Ctlz, *CtlzOp;
3863 bool ShouldDropNoWrap;
3870 !isSafeToRemoveBitCeilSelect(Pred, Cond0, Cond1, CtlzOp,
BitWidth,
3874 if (ShouldDropNoWrap) {
3906 Value *TV =
SI.getTrueValue();
3907 Value *FV =
SI.getFalseValue();
3928 auto FlippedPredAndConst =
3930 if (!FlippedPredAndConst)
3932 Pred = FlippedPredAndConst->first;
3933 RHS = FlippedPredAndConst->second;
3950 bool Replace =
false;
3951 CmpPredicate ExtendedCmpPredicate;
3971 CmpPredicate FalseBranchSelectPredicate;
3972 const APInt *InnerTV, *InnerFV;
3978 FalseBranchSelectPredicate =
3983 if (!InnerTV->
isOne()) {
3999 CmpPredicate InnerPred;
4001 const APInt *InnerTV, *InnerFV;
4010 bool CanSubOne = IsSigned ? !
C->isMinSignedValue() : !
C->isMinValue();
4012 APInt Cminus1 = *
C - 1;
4022 bool CanAddOne = IsSigned ? !
C->isMaxSignedValue() : !
C->isMaxValue();
4024 APInt Cplus1 = *
C + 1;
4033 Intrinsic::ID IID = IsSigned ? Intrinsic::scmp : Intrinsic::ucmp;
4036 SI,
Builder.CreateIntrinsic(
SI.getType(), IID, {LHS, RHS}));
4084 return Op->getType()->isIntOrIntVectorTy() &&
4085 hasAffectedValue(Op, Affected, Depth + 1);
4099 if (!SIFOp || !SIFOp->hasNoSignedZeros() || !SIFOp->hasNoNaNs())
4102 auto TryFoldIntoAddConstant =
4114 Swapped ?
X : Z,
"", &
SI);
4145 return TryFoldIntoAddConstant(Pred,
X, Z,
FAdd,
C,
false);
4149 return TryFoldIntoAddConstant(Pred,
X, Z,
FAdd,
C,
true);
4165 bool CreateAnd =
false;
4167 Value *CmpLHS, *CmpRHS;
4175 const APInt *AndRHS;
4182 AndMask = Res->Mask;
4195 V = Trunc->getOperand(0);
4196 AndMask =
APInt(
V->getType()->getScalarSizeInBits(), 1);
4198 CreateAnd = !Trunc->hasNoUnsignedWrap();
4207 CreateAnd, Builder))
4211 CreateAnd, Builder))
4218 Value *CondVal =
SI.getCondition();
4221 Type *SelType =
SI.getType();
4224 SQ.getWithInstruction(&SI)))
4227 if (Instruction *
I = canonicalizeSelectToShuffle(SI))
4230 if (Instruction *
I = canonicalizeScalarSelectOfVecs(SI, *
this))
4272 return new ZExtInst(CondVal, SelType);
4276 return new SExtInst(CondVal, SelType);
4281 return new ZExtInst(NotCond, SelType);
4287 return new SExtInst(NotCond, SelType);
4295 Value *Cmp0 = FCmp->getOperand(0), *Cmp1 = FCmp->getOperand(1);
4297 if ((Cmp0 == TrueVal && Cmp1 == FalseVal) ||
4298 (Cmp0 == FalseVal && Cmp1 == TrueVal)) {
4306 Value *NewCond =
Builder.CreateFCmpFMF(InvPred, Cmp0, Cmp1, FCmp,
4307 FCmp->getName() +
".inv");
4309 FastMathFlags FMF =
SI.getFastMathFlags();
4310 if (FCmp->hasNoNaNs())
4312 if (FCmp->hasNoInfs())
4315 Builder.CreateSelectFMF(NewCond, FalseVal, TrueVal, FMF);
4334 Value *MatchCmp0 =
nullptr;
4335 Value *MatchCmp1 =
nullptr;
4347 if (Cmp0 == MatchCmp0 &&
4348 matchFMulByZeroIfResultEqZero(*
this, Cmp0, Cmp1, MatchCmp1, MatchCmp0,
4349 SI, SIFPOp->hasNoSignedZeros()))
4374 if (FCmp && FCmp->hasNoNaNs() &&
4375 (SIFPOp->hasNoSignedZeros() ||
4376 (SIFPOp->hasOneUse() &&
4381 Builder.CreateBinaryIntrinsic(Intrinsic::maxnum,
X,
Y, &SI);
4385 BinIntrInst->setHasNoInfs(FCmp->hasNoInfs());
4391 BinIntrInst->setHasNoSignedZeros(
true);
4394 BinIntrInst->setHasNoNaNs(
true);
4401 Builder.CreateBinaryIntrinsic(Intrinsic::minnum,
X,
Y, &SI);
4403 BinIntrInst->setHasNoInfs(FCmp->hasNoInfs());
4404 BinIntrInst->setHasNoSignedZeros(
true);
4405 BinIntrInst->setHasNoNaNs(
true);
4413 if (Instruction *Fabs = foldSelectWithFCmpToFabs(SI, *
this))
4425 if (
Value *V = foldSelectBitTest(SI, CondVal, TrueVal, FalseVal,
Builder,
SQ))
4428 if (Instruction *
Add = foldAddSubSelect(SI,
Builder))
4430 if (Instruction *
Add = foldOverflowingAddSubSelect(SI,
Builder))
4440 if (TI && FI && TI->getOpcode() == FI->getOpcode())
4447 if (Instruction *
I = foldSelectWithSRem(SI, *
this,
Builder))
4452 auto SelectGepWithBase = [&](GetElementPtrInst *Gep,
Value *
Base,
4453 bool Swap) -> GetElementPtrInst * {
4467 Builder.CreateSelect(CondVal, NewT, NewF,
SI.getName() +
".idx", &SI);
4472 if (
auto *NewGep = SelectGepWithBase(TrueGep, FalseVal,
false))
4475 if (
auto *NewGep = SelectGepWithBase(FalseGep, TrueVal,
true))
4491 RHS2, SI, SPF,
RHS))
4495 RHS2, SI, SPF,
LHS))
4504 bool IsCastNeeded =
LHS->
getType() != SelType;
4509 ((CmpLHS !=
LHS && CmpLHS !=
RHS) ||
4510 (CmpRHS !=
LHS && CmpRHS !=
RHS)))) {
4524 Value *NewCast =
Builder.CreateCast(CastOp, NewSI, SelType);
4536 if (TrueSI->getCondition()->getType() == CondVal->
getType()) {
4539 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(
4540 *TrueSI, CondVal,
true,
DL))
4546 if (TrueSI->hasOneUse()) {
4547 Value *
And =
nullptr, *OtherVal =
nullptr;
4549 if (TrueSI->getFalseValue() == FalseVal) {
4550 And =
Builder.CreateLogicalAnd(CondVal, TrueSI->getCondition(),
"",
4553 OtherVal = TrueSI->getTrueValue();
4556 else if (TrueSI->getTrueValue() == FalseVal) {
4557 Value *InvertedCond =
Builder.CreateNot(TrueSI->getCondition());
4558 And =
Builder.CreateLogicalAnd(CondVal, InvertedCond,
"",
4561 OtherVal = TrueSI->getFalseValue();
4563 if (
And && OtherVal) {
4574 if (FalseSI->getCondition()->getType() == CondVal->
getType()) {
4577 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(
4578 *FalseSI, CondVal,
false,
DL))
4581 if (FalseSI->hasOneUse()) {
4582 Value *
Or =
nullptr, *OtherVal =
nullptr;
4584 if (FalseSI->getTrueValue() == TrueVal) {
4585 Or =
Builder.CreateLogicalOr(CondVal, FalseSI->getCondition(),
"",
4588 OtherVal = FalseSI->getFalseValue();
4591 else if (FalseSI->getFalseValue() == TrueVal) {
4592 Value *InvertedCond =
Builder.CreateNot(FalseSI->getCondition());
4593 Or =
Builder.CreateLogicalOr(CondVal, InvertedCond,
"",
4596 OtherVal = FalseSI->getTrueValue();
4598 if (
Or && OtherVal) {
4615 BinaryOperator *TrueBO;
4618 if (TrueBOSI->getCondition() == CondVal) {
4625 if (TrueBOSI->getCondition() == CondVal) {
4634 BinaryOperator *FalseBO;
4637 if (FalseBOSI->getCondition() == CondVal) {
4644 if (FalseBOSI->getCondition() == CondVal) {
4657 SI.swapProfMetadata();
4678 if (Instruction *BitCastSel = foldSelectCmpBitcasts(SI,
Builder))
4682 if (
Value *V = foldSelectCmpXchg(SI))
4688 if (Instruction *Funnel = foldSelectFunnelShift(SI,
Builder))
4691 if (Instruction *Copysign = foldSelectToCopysign(SI,
Builder))
4694 if (Instruction *PN = foldSelectToPhi(SI,
DT,
Builder))
4697 if (
Value *V = foldRoundUpIntegerWithPow2Alignment(SI,
Builder))
4712 MaskedInst->setArgOperand(2, FalseVal );
4727 bool CanMergeSelectIntoLoad =
false;
4731 if (CanMergeSelectIntoLoad) {
4734 MaskedInst->setArgOperand(2, TrueVal );
4739 if (Instruction *
I = foldSelectOfSymmetricSelect(SI,
Builder))
4742 if (Instruction *
I = foldNestedSelects(SI,
Builder))
4752 if (Instruction *
I = foldBitCeil(SI,
Builder, *
this))
4766 auto FoldSelectWithAndOrCond = [&](
bool IsAnd,
Value *
A,
4767 Value *
B) -> Instruction * {
4769 SQ.getWithInstruction(&SI))) {
4777 if (NewTrueVal == TrueVal && NewFalseVal == FalseVal &&
4788 if (
Value *V = canonicalizeSPF(*Cmp, TrueVal, FalseVal, *
this))
4790 IsAnd ? FalseVal : V);
4798 if (Instruction *
I = FoldSelectWithAndOrCond(
true,
LHS,
RHS))
4800 if (Instruction *
I = FoldSelectWithAndOrCond(
true,
RHS,
LHS))
4803 if (Instruction *
I = FoldSelectWithAndOrCond(
false,
LHS,
RHS))
4805 if (Instruction *
I = FoldSelectWithAndOrCond(
false,
RHS,
LHS))
4811 if (Instruction *
I = FoldSelectWithAndOrCond(
true,
LHS,
RHS))
4814 if (Instruction *
I = FoldSelectWithAndOrCond(
false,
LHS,
RHS))
4821 return BinaryOperator::CreateXor(CondVal, FalseVal);
4828 CondContext CC(CondVal);
4830 CC.AffectedValues.insert(V);
4832 SimplifyQuery Q =
SQ.getWithInstruction(&SI).getWithCondContext(CC);
4833 if (!CC.AffectedValues.empty()) {
4835 hasAffectedValue(TrueVal, CC.AffectedValues, 0)) {
4844 hasAffectedValue(FalseVal, CC.AffectedValues, 0)) {
4859 if (TrueVal == Trunc)
4861 if (FalseVal == Trunc)
4865 if (TrueVal == Trunc)
4868 if (FalseVal == Trunc)
4872 Value *MaskedLoadPtr;
4877 TrueVal->getType(), MaskedLoadPtr,
4879 CondVal, FalseVal));
4884 unsigned BitWidth =
SI.getType()->getScalarSizeInBits();
4886 Value *CmpLHS, *CmpRHS;
4903 SI.getModule(), Intrinsic::scmp, {SI.getType(), SI.getType()});
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< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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 * canonicalizeSaturatedAddSigned(ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
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) ?
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 * canonicalizeSaturatedAddUnsigned(ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
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.
Machine Check Debug Module
uint64_t IntrinsicInst * II
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton 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),...
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.
static bool isFPPredicate(Predicate P)
bool isNonStrictPredicate() const
static bool isRelational(Predicate P)
Return true if the predicate is relational (not EQ or NE).
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.
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?
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.
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 ...
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.
This instruction compares its operands according to the predicate given to the constructor.
static CmpPredicate getSwappedCmpPredicate(CmpPredicate Pred)
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.
static CmpPredicate getInverseCmpPredicate(CmpPredicate Pred)
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 * CreateFAdd(Value *L, Value *R, const Twine &Name="", MDNode *FPMD=nullptr)
LLVM_ABI Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")
Return a vector value that contains.
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 * 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.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
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 * 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)
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 * 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 * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, 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)
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
IRBuilder< TargetFolder, IRBuilderCallbackInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
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)
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.
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.
const Value * getFalseValue() const
void swapValues()
Swap the true and false values of the select instruction.
const Value * getCondition() const
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
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.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
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)
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.
BinaryOpc_match< LHS, RHS, false > m_BinOp(unsigned Opcode, const LHS &L, const RHS &R)
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)
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.
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)
CommutativeBinaryIntrinsic_match< IntrID, T0, T1 > m_c_Intrinsic(const T0 &Op0, const T1 &Op1)
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
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)
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
LogicalOp_match< LHS, RHS, Instruction::And > m_LogicalAnd(const LHS &L, const RHS &R)
Matches L && R either in the form of L & R or L ?
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWSub(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)
ap_match< APFloat > m_APFloatAllowPoison(const APFloat *&Res)
Match APFloat while allowing poison in splat vector constants.
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.
auto match_fn(const Pattern &P)
A match functor that can be used as a UnaryPredicate in functional algorithms like all_of.
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'.
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_MaskedLoad(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
Matches MaskedLoad Intrinsic.
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.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
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.
ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)
Match a single index ExtractValue instruction.
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()...
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.
ap_match< APInt > m_APIntForbidPoison(const APInt *&Res)
Match APInt while forbidding poison in splat vector constants.
cst_pred_ty< is_strictlypositive > m_StrictlyPositive()
Match an integer or vector of strictly positive values.
SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
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.
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_MaskedGather(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
Matches MaskedGather Intrinsic.
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)
cst_pred_ty< is_maxsignedvalue > m_MaxSignedValue()
Match an integer or vector with values having all bits except for the high bit set (0x7f....
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)
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
NodeAddr< UseNode * > Use
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
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.
LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I, StringRef PassName, const Function *F=nullptr)
Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch weights in the new instruct...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
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 canReplacePointersIfEqual(const Value *From, const Value *To, const DataLayout &DL)
Returns true if a pointer value From can be replaced with another pointer value \To if they are deeme...
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.
FunctionAddr VTableAddr Count
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.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI bool isKnownInversion(const Value *X, const Value *Y)
Return true iff:
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
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...
@ 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.
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 Constant * getLosslessInvCast(Constant *C, Type *InvCastTo, unsigned CastOp, const DataLayout &DL, PreservedCastFlags *Flags=nullptr)
Try to cast C to InvC losslessly, satisfying CastOp(InvC) equals C, or CastOp(InvC) is a refined valu...
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.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
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.
cl::opt< bool > ProfcheckDisableMetadataFixes("profcheck-disable-metadata-fixes", cl::Hidden, cl::init(false), cl::desc("Disable metadata propagation fixes discovered through Issue #147390"))
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.
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 getWithInstruction(const Instruction *I) const