46#define DEBUG_TYPE "instcombine"
50using namespace PatternMatch;
67 IsEq = Pred == ICmpInst::ICMP_EQ;
68 else if (Pred == FCmpInst::FCMP_OEQ)
70 else if (Pred == FCmpInst::FCMP_UNE)
100 if (isa<FPMathOperator>(BO))
124 const APInt *SelTC, *SelFC;
131 if (SelType->
isVectorTy() != Cmp->getType()->isVectorTy())
136 bool CreateAnd =
false;
142 V = Cmp->getOperand(0);
158 if (Pred == ICmpInst::ICMP_NE)
165 const APInt &TC = *SelTC;
166 const APInt &FC = *SelFC;
167 if (!TC.
isZero() && !FC.isZero()) {
172 if (CreateAnd && !Cmp->hasOneUse())
179 Constant *TCC = ConstantInt::get(SelType, TC);
180 Constant *FCC = ConstantInt::get(SelType, FC);
181 Constant *MaskC = ConstantInt::get(SelType, AndMask);
182 for (
auto Opc : {Instruction::Or, Instruction::Xor, Instruction::Add,
202 unsigned ValZeros = ValC.
logBase2();
203 unsigned AndZeros = AndMask.
logBase2();
204 bool ShouldNotVal = !TC.
isZero();
209 if (CreateAnd && ShouldNotVal && ValZeros != AndZeros)
214 V = Builder.
CreateAnd(V, ConstantInt::get(V->getType(), AndMask));
218 if (ValZeros > AndZeros) {
220 V = Builder.
CreateShl(V, ValZeros - AndZeros);
221 }
else if (ValZeros < AndZeros) {
222 V = Builder.
CreateLShr(V, AndZeros - ValZeros);
247 switch (
I->getOpcode()) {
248 case Instruction::Add:
249 case Instruction::FAdd:
250 case Instruction::Mul:
251 case Instruction::FMul:
252 case Instruction::And:
253 case Instruction::Or:
254 case Instruction::Xor:
256 case Instruction::Sub:
257 case Instruction::FSub:
258 case Instruction::FDiv:
259 case Instruction::Shl:
260 case Instruction::LShr:
261 case Instruction::AShr:
291 if (
auto *CondVTy = dyn_cast<VectorType>(CondTy)) {
293 CondVTy->getElementCount() !=
294 cast<VectorType>(FIOpndTy)->getElementCount())
305 if (TI->
getOpcode() != Instruction::BitCast &&
318 SI.getName() +
".v", &SI);
323 Value *OtherOpT, *OtherOpF;
326 bool Swapped =
false) ->
Value * {
327 assert(!(Commute && Swapped) &&
328 "Commute and Swapped can't set at the same time");
333 MatchIsOpZero =
true;
338 MatchIsOpZero =
false;
343 if (!Commute && !Swapped)
352 MatchIsOpZero =
true;
357 MatchIsOpZero =
false;
371 FMF |= SI.getFastMathFlags();
374 if (
auto *NewSelI = dyn_cast<Instruction>(NewSel))
375 NewSelI->setFastMathFlags(FMF);
376 Instruction *NewFNeg = UnaryOperator::CreateFNeg(NewSel);
385 auto *
TII = dyn_cast<IntrinsicInst>(TI);
386 auto *FII = dyn_cast<IntrinsicInst>(FI);
387 if (
TII && FII &&
TII->getIntrinsicID() == FII->getIntrinsicID()) {
389 if (
Value *MatchOp = getCommonOp(TI, FI,
true)) {
401 if (
TII->getIntrinsicID() == Intrinsic::ldexp) {
402 Value *LdexpVal0 =
TII->getArgOperand(0);
403 Value *LdexpExp0 =
TII->getArgOperand(1);
404 Value *LdexpVal1 = FII->getArgOperand(0);
405 Value *LdexpExp1 = FII->getArgOperand(1);
409 FMF &= cast<FPMathOperator>(FII)->getFastMathFlags();
416 TII->
getType(), Intrinsic::ldexp, {SelectVal, SelectExp});
429 bool Swapped = TPred != FPred;
433 SI.getName() +
".v", &SI);
448 (!isa<BinaryOperator>(TI) && !isa<GetElementPtrInst>(TI)) ||
470 auto *BO = dyn_cast<BinaryOperator>(TI);
474 if (BO->getOpcode() == Instruction::SDiv ||
475 BO->getOpcode() == Instruction::SRem || MatchIsOpZero)
481 SI.getName() +
".v", &SI);
482 Value *Op0 = MatchIsOpZero ? MatchOp : NewSI;
483 Value *Op1 = MatchIsOpZero ? NewSI : MatchOp;
484 if (
auto *BO = dyn_cast<BinaryOperator>(TI)) {
490 if (
auto *TGEP = dyn_cast<GetElementPtrInst>(TI)) {
491 auto *FGEP = cast<GetElementPtrInst>(FI);
492 Type *ElementType = TGEP->getSourceElementType();
494 ElementType, Op0, Op1, TGEP->getNoWrapFlags() & FGEP->getNoWrapFlags());
515 auto *TVI = dyn_cast<BinaryOperator>(TrueVal);
516 if (!TVI || !TVI->hasOneUse() || isa<Constant>(FalseVal))
520 unsigned OpToFold = 0;
521 if ((SFO & 1) && FalseVal == TVI->getOperand(0))
523 else if ((SFO & 2) && FalseVal == TVI->getOperand(1))
533 if (isa<FPMathOperator>(&SI))
534 FMF = SI.getFastMathFlags();
536 TVI->getOpcode(), TVI->getType(),
true, FMF.
noSignedZeros());
537 Value *OOp = TVI->getOperand(2 - OpToFold);
542 if (isa<Constant>(OOp) &&
543 (!OOpIsAPInt || !
isSelect01(
C->getUniqueInteger(), *OOpC)))
552 if (isa<FPMathOperator>(&SI) &&
557 Swapped ? OOp :
C,
"", &SI);
558 if (isa<FPMathOperator>(&SI))
559 cast<Instruction>(NewSel)->setFastMathFlags(FMF);
567 if (
Instruction *R = TryFoldSelectIntoOp(SI, TrueVal, FalseVal,
false))
570 if (
Instruction *R = TryFoldSelectIntoOp(SI, FalseVal, TrueVal,
true))
587 if (!(Cmp->hasOneUse() && Cmp->getOperand(0)->hasOneUse() &&
619 Constant *One = ConstantInt::get(SelType, 1);
624 return new ZExtInst(ICmpNeZero, SelType);
646 const APInt *C2, *C1;
656 auto *FI = dyn_cast<Instruction>(FVal);
660 FI->setHasNoSignedWrap(
false);
661 FI->setHasNoUnsignedWrap(
false);
696 const auto *Ashr = cast<Instruction>(FalseVal);
698 bool IsExact = Ashr->isExact() && cast<Instruction>(TrueVal)->isExact();
730 if (!TrueVal->getType()->isIntOrIntVectorTy() ||
765 BinOp = cast<BinaryOperator>(FalseVal);
769 BinOp = cast<BinaryOperator>(TrueVal);
779 if (IdentityC ==
nullptr || !IdentityC->isNullValue())
784 bool NeedShift = C1Log != C2Log;
785 bool NeedZExtTrunc =
Y->getType()->getScalarSizeInBits() !=
786 V->getType()->getScalarSizeInBits();
789 if ((NeedShift + NeedXor + NeedZExtTrunc +
NeedAnd) >
796 V = Builder.
CreateAnd(V, ConstantInt::get(V->getType(), C1));
802 }
else if (C1Log > C2Log) {
829 Constant *OrC = ConstantInt::get(Ty, *
C);
831 return BinaryOperator::CreateOr(
T, NewSel);
838 Constant *OrC = ConstantInt::get(Ty, *
C);
840 return BinaryOperator::CreateOr(
F, NewSel);
857 auto *CondVal = SI.getCondition();
858 auto *TrueVal = SI.getTrueValue();
859 auto *FalseVal = SI.getFalseValue();
877 auto *TrueValC = dyn_cast<Constant>(TrueVal);
878 if (TrueValC ==
nullptr ||
880 !isa<Instruction>(FalseVal))
883 auto *ZeroC = cast<Constant>(cast<Instruction>(CondVal)->getOperand(1));
891 auto *FalseValI = cast<Instruction>(FalseVal);
894 IC.
replaceOperand(*FalseValI, FalseValI->getOperand(0) ==
Y ? 0 : 1, FrY);
901 const Value *TrueVal,
902 const Value *FalseVal,
923 ConstantInt::get(
A->getType(), 1));
937 "Unexpected isUnsigned predicate!");
943 bool IsNegative =
false;
956 if (IsNegative && !TrueVal->hasOneUse() && !ICI->
hasOneUse())
969 if (!Cmp->hasOneUse())
973 Value *Cmp0 = Cmp->getOperand(0);
974 Value *Cmp1 = Cmp->getOperand(1);
995 Intrinsic::uadd_sat, Cmp0, ConstantInt::get(Cmp0->
getType(), 1));
1006 ConstantInt::get(Cmp0->
getType(), *
C));
1016 ConstantInt::get(Cmp0->
getType(), *
C));
1026 ConstantInt::get(Cmp0->
getType(), *
C));
1073 auto *TI = dyn_cast<Instruction>(TVal);
1074 auto *FI = dyn_cast<Instruction>(FVal);
1080 Value *
A = Cmp->getOperand(0);
1081 Value *
B = Cmp->getOperand(1);
1094 (TI->hasNoSignedWrap() || TI->hasNoUnsignedWrap()) &&
1095 (FI->hasNoSignedWrap() || FI->hasNoUnsignedWrap())) {
1102 TI->setHasNoUnsignedWrap(
false);
1103 if (!TI->hasNoSignedWrap())
1104 TI->setHasNoSignedWrap(TI->hasOneUse());
1132 if (!
match(FalseVal,
1136 if (!
match(Ctlz, m_Intrinsic<Intrinsic::ctlz>()))
1143 auto *
II = cast<IntrinsicInst>(Ctlz);
1180 Value *Count =
nullptr;
1188 if (!
match(Count, m_Intrinsic<Intrinsic::cttz>(
m_Value(
X))) &&
1208 II->dropPoisonGeneratingAnnotations();
1227 if (!
TrueVal->getType()->isIntOrIntVectorTy())
1254 IntrinsicID = Intrinsic::umin;
1257 IntrinsicID = Intrinsic::umax;
1260 IntrinsicID = Intrinsic::smin;
1263 IntrinsicID = Intrinsic::smax;
1280 assert(!isa<Constant>(Old) &&
"Only replace non-constant values");
1282 auto *
I = dyn_cast<Instruction>(V);
1283 if (!
I || !
I->hasOneUse() ||
1287 bool Changed =
false;
1288 for (
Use &U :
I->operands()) {
1318 if (!
Cmp.isEquality())
1323 bool Swapped =
false;
1329 Value *CmpLHS =
Cmp.getOperand(0), *CmpRHS =
Cmp.getOperand(1);
1330 auto ReplaceOldOpWithNewOp = [&](
Value *OldOp,
1338 if (TrueVal == OldOp)
1374 if (
Instruction *R = ReplaceOldOpWithNewOp(CmpLHS, CmpRHS))
1376 if (
Instruction *R = ReplaceOldOpWithNewOp(CmpRHS, CmpLHS))
1379 auto *FalseInst = dyn_cast<Instruction>(FalseVal);
1394 &DropFlags) == TrueVal ||
1397 &DropFlags) == TrueVal) {
1399 I->dropPoisonGeneratingAnnotations();
1440 if (!isa<SelectInst>(Sel1)) {
1481 if (Cmp00->
getType() !=
X->getType() &&
X->hasOneUse())
1489 else if (!
match(Cmp00,
1497 Value *ReplacementLow, *ReplacementHigh;
1534 std::swap(ReplacementLow, ReplacementHigh);
1540 "Unexpected predicate type.");
1548 "Unexpected predicate type.");
1550 std::swap(ThresholdLowIncl, ThresholdHighExcl);
1566 if (
X->getType() != Sel0.
getType()) {
1576 assert(ReplacementLow && ReplacementHigh &&
1577 "Constant folding of ImmConstant cannot fail");
1583 Value *MaybeReplacedLow =
1589 ShouldReplaceHigh, ReplacementHigh, MaybeReplacedLow);
1633 Value *SelVal0, *SelVal1;
1642 auto MatchesSelectValue = [SelVal0, SelVal1](
Constant *
C) {
1643 return C->isElementWiseEqual(SelVal0) ||
C->isElementWiseEqual(SelVal1);
1647 if (MatchesSelectValue(C0))
1651 auto FlippedStrictness =
1653 if (!FlippedStrictness)
1657 if (!MatchesSelectValue(FlippedStrictness->second))
1666 Cmp.getName() +
".inv");
1677 if (!
Cmp->hasOneUse())
1707 Value *TVal =
SI.getTrueValue();
1708 Value *FVal =
SI.getFalseValue();
1734 const APInt *BinOpC;
1771 const unsigned AndOps = Instruction::And, OrOps = Instruction::Or,
1772 XorOps = Instruction::Xor, NoOps = 0;
1773 enum NotMask {
None = 0, NotInner, NotRHS };
1775 auto matchFalseVal = [&](
unsigned OuterOpc,
unsigned InnerOpc,
1778 if (OuterOpc == NoOps)
1781 if (NotMask == NotInner) {
1784 }
else if (NotMask == NotRHS) {
1788 return match(FalseVal,
1799 if (matchFalseVal(OrOps, XorOps,
None) ||
1800 matchFalseVal(XorOps, XorOps,
None))
1805 if (matchFalseVal(XorOps, OrOps,
None) ||
1806 matchFalseVal(AndOps, OrOps, NotRHS))
1817 if (matchFalseVal(XorOps, XorOps,
None) ||
1818 matchFalseVal(AndOps, XorOps, NotInner))
1823 if (matchFalseVal(XorOps, AndOps,
None) ||
1824 matchFalseVal(AndOps, AndOps, NotInner))
1835 if (matchFalseVal(XorOps, OrOps,
None) ||
1836 matchFalseVal(AndOps, OrOps, NotRHS))
1841 if (matchFalseVal(OrOps, AndOps,
None) ||
1842 matchFalseVal(XorOps, AndOps,
None))
1857 canonicalizeSPF(*ICI,
SI.getTrueValue(),
SI.getFalseValue(), *
this))
1860 if (
Value *V = foldSelectInstWithICmpConst(SI, ICI,
Builder))
1863 if (
Value *V = canonicalizeClampLike(SI, *ICI,
Builder, *
this))
1867 tryToReuseConstantFromSelectInComparison(SI, *ICI, *
this))
1874 bool Changed =
false;
1880 if (CmpRHS != CmpLHS && isa<Constant>(CmpRHS) && !isa<Constant>(CmpLHS)) {
1892 if (
Instruction *NewSel = foldSelectICmpEq(SI, ICI, *
this))
1907 SI.swapProfMetadata();
1913 if (
TrueVal->getType()->isIntOrIntVectorTy()) {
1920 bool IsBitTest =
false;
1928 Y = &MinSignedValue;
1930 TrueWhenUnset =
false;
1933 Y = &MinSignedValue;
1935 TrueWhenUnset =
true;
1940 if (TrueWhenUnset && TrueVal ==
X &&
1944 else if (!TrueWhenUnset && FalseVal ==
X &&
1948 else if (TrueWhenUnset && FalseVal ==
X &&
1952 else if (!TrueWhenUnset && TrueVal ==
X &&
1980 if (
Value *V = foldSelectCttzCtlz(ICI, TrueVal, FalseVal, *
this))
1992 return Changed ? &
SI :
nullptr;
2004static bool canSelectOperandBeMappingIntoPredBlock(
const Value *V,
2009 if (!
I)
return true;
2013 const PHINode *CondPHI = cast<PHINode>(
SI.getCondition());
2015 if (
const PHINode *VP = dyn_cast<PHINode>(
I))
2016 if (VP->getParent() == CondPHI->
getParent())
2040 if (
C ==
A ||
C ==
B) {
2055 Value *CondVal =
SI.getCondition();
2058 auto *TI = dyn_cast<Instruction>(TrueVal);
2059 auto *FI = dyn_cast<Instruction>(FalseVal);
2060 if (!TI || !FI || !TI->hasOneUse() || !FI->hasOneUse())
2064 if ((TI->getOpcode() == Instruction::Sub &&
2065 FI->getOpcode() == Instruction::Add) ||
2066 (TI->getOpcode() == Instruction::FSub &&
2067 FI->getOpcode() == Instruction::FAdd)) {
2070 }
else if ((FI->getOpcode() == Instruction::Sub &&
2071 TI->getOpcode() == Instruction::Add) ||
2072 (FI->getOpcode() == Instruction::FSub &&
2073 TI->getOpcode() == Instruction::FAdd)) {
2079 Value *OtherAddOp =
nullptr;
2080 if (SubOp->getOperand(0) == AddOp->
getOperand(0)) {
2082 }
else if (SubOp->getOperand(0) == AddOp->
getOperand(1)) {
2090 if (
SI.getType()->isFPOrFPVectorTy()) {
2091 NegVal = Builder.
CreateFNeg(SubOp->getOperand(1));
2092 if (
Instruction *NegInst = dyn_cast<Instruction>(NegVal)) {
2094 Flags &= SubOp->getFastMathFlags();
2095 NegInst->setFastMathFlags(Flags);
2098 NegVal = Builder.
CreateNeg(SubOp->getOperand(1));
2101 Value *NewTrueOp = OtherAddOp;
2102 Value *NewFalseOp = NegVal;
2106 SI.getName() +
".p", &SI);
2108 if (
SI.getType()->isFPOrFPVectorTy()) {
2110 BinaryOperator::CreateFAdd(SubOp->getOperand(0), NewSel);
2113 Flags &= SubOp->getFastMathFlags();
2117 return BinaryOperator::CreateAdd(SubOp->getOperand(0), NewSel);
2130 Value *CondVal =
SI.getCondition();
2142 auto IsSignedSaturateLimit = [&](
Value *Limit,
bool IsAdd) {
2152 auto IsZeroOrOne = [](
const APInt &
C) {
return C.isZero() ||
C.isOne(); };
2169 IsMinMax(TrueVal, FalseVal))
2176 IsMinMax(FalseVal, TrueVal))
2182 IsMinMax(TrueVal, FalseVal))
2187 IsMinMax(FalseVal, TrueVal))
2192 IsMinMax(FalseVal, TrueVal))
2197 IsMinMax(TrueVal, FalseVal))
2205 if (
II->getIntrinsicID() == Intrinsic::uadd_with_overflow &&
2208 NewIntrinsicID = Intrinsic::uadd_sat;
2209 else if (
II->getIntrinsicID() == Intrinsic::usub_with_overflow &&
2212 NewIntrinsicID = Intrinsic::usub_sat;
2213 else if (
II->getIntrinsicID() == Intrinsic::sadd_with_overflow &&
2214 IsSignedSaturateLimit(TrueVal,
true))
2223 NewIntrinsicID = Intrinsic::sadd_sat;
2224 else if (
II->getIntrinsicID() == Intrinsic::ssub_with_overflow &&
2225 IsSignedSaturateLimit(TrueVal,
false))
2234 NewIntrinsicID = Intrinsic::ssub_sat;
2255 if (ExtOpcode != Instruction::ZExt && ExtOpcode != Instruction::SExt)
2261 Type *SmallType =
X->getType();
2263 auto *
Cmp = dyn_cast<CmpInst>(
Cond);
2265 (!Cmp ||
Cmp->getOperand(0)->getType() != SmallType))
2273 Value *TruncCVal = cast<Value>(TruncC);
2289 Value *CondVal =
SI.getCondition();
2291 auto *CondValTy = dyn_cast<FixedVectorType>(CondVal->
getType());
2295 unsigned NumElts = CondValTy->getNumElements();
2297 Mask.reserve(NumElts);
2298 for (
unsigned i = 0; i != NumElts; ++i) {
2308 Mask.push_back(i + NumElts);
2309 }
else if (isa<UndefValue>(Elt)) {
2329 auto *Ty = dyn_cast<VectorType>(Sel.
getType());
2361 if (TVal ==
A || TVal ==
B || FVal ==
A || FVal ==
B)
2378 if (TSrc ==
C && FSrc ==
D) {
2382 }
else if (TSrc ==
D && FSrc ==
C) {
2421 auto *Extract = dyn_cast<ExtractValueInst>(V);
2424 if (Extract->getIndices()[0] !=
I)
2426 return dyn_cast<AtomicCmpXchgInst>(Extract->getAggregateOperand());
2432 if (
auto *
Select = dyn_cast<SelectInst>(
SI.user_back()))
2433 if (
Select->getCondition() ==
SI.getCondition())
2434 if (
Select->getFalseValue() ==
SI.getTrueValue() ||
2435 Select->getTrueValue() ==
SI.getFalseValue())
2439 auto *CmpXchg = isExtractFromCmpXchg(
SI.getCondition(), 1);
2446 if (
auto *
X = isExtractFromCmpXchg(
SI.getTrueValue(), 0))
2447 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getFalseValue())
2448 return SI.getFalseValue();
2453 if (
auto *
X = isExtractFromCmpXchg(
SI.getFalseValue(), 0))
2454 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getTrueValue())
2455 return SI.getFalseValue();
2479 Value *SV0, *SV1, *SA0, *SA1;
2488 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2494 Or1->
getOpcode() == BinaryOperator::LShr &&
2495 "Illegal or(shift,shift) pair");
2510 bool IsFshl = (ShAmt == SA0);
2512 if ((IsFshl && TVal != SV0) || (!IsFshl && TVal != SV1))
2532 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
2553 assert(TC != FC &&
"Expected equal select arms to simplify");
2557 bool IsTrueIfSignSet;
2575 Value *MagArg = ConstantFP::get(SelType,
abs(*TC));
2582 if (!isa<VectorType>(Sel.
getType()))
2593 if (
auto *
I = dyn_cast<Instruction>(V))
2594 I->copyIRFlags(&Sel);
2605 return createSelReverse(
C,
X,
Y);
2609 return createSelReverse(
C,
X, FVal);
2614 return createSelReverse(
C, TVal,
Y);
2617 auto *VecTy = dyn_cast<FixedVectorType>(Sel.
getType());
2621 unsigned NumElts = VecTy->getNumElements();
2622 APInt PoisonElts(NumElts, 0);
2636 cast<ShuffleVectorInst>(TVal)->isSelect()) {
2650 cast<ShuffleVectorInst>(FVal)->isSelect()) {
2671 auto *IDomNode = DT[BB]->getIDom();
2677 Value *IfTrue, *IfFalse;
2693 if (TrueSucc == FalseSucc)
2714 if (
auto *
Insn = dyn_cast<Instruction>(Inputs[Pred]))
2733 if (
auto *
I = dyn_cast<Instruction>(V))
2734 CandidateBlocks.
insert(
I->getParent());
2737 if (
auto *PN = foldSelectToPhiImpl(Sel, BB, DT, Builder))
2750 Value *CondVal =
SI.getCondition();
2755 Value *
Op, *RemRes, *Remainder;
2757 bool TrueIfSigned =
false;
2771 return BinaryOperator::CreateAnd(
Op,
Add);
2783 return FoldToBitwiseAnd(Remainder);
2792 return FoldToBitwiseAnd(ConstantInt::get(RemRes->
getType(), 2));
2828 Value *InnerCondVal =
SI.getCondition();
2829 Value *InnerTrueVal =
SI.getTrueValue();
2830 Value *InnerFalseVal =
SI.getFalseValue();
2832 "The type of inner condition must match with the outer.");
2834 return *Implied ? InnerTrueVal : InnerFalseVal;
2841 assert(
Op->getType()->isIntOrIntVectorTy(1) &&
2842 "Op must be either i1 or vector of i1.");
2843 if (
SI.getCondition()->getType() !=
Op->getType())
2845 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(SI,
Op, IsAnd,
DL))
2856 Value *CondVal =
SI.getCondition();
2858 bool ChangedFMF =
false;
2859 for (
bool Swap : {
false,
true}) {
2889 FastMathFlags FMF = cast<FPMathOperator>(TrueVal)->getFastMathFlags();
2890 if (FMF.
noNaNs() && !
SI.hasNoNaNs()) {
2891 SI.setHasNoNaNs(
true);
2894 if (FMF.
noInfs() && !
SI.hasNoInfs()) {
2895 SI.setHasNoInfs(
true);
2909 if (!
SI.hasNoSignedZeros() || !
SI.hasNoNaNs())
2926 Instruction *NewFNeg = UnaryOperator::CreateFNeg(Fabs);
2935 for (
bool Swap : {
false,
true}) {
2951 if (Swap == TrueIfSigned && !CondVal->
hasOneUse() && !
TrueVal->hasOneUse())
2957 if (Swap != TrueIfSigned)
2962 return ChangedFMF ? &
SI :
nullptr;
2980foldRoundUpIntegerWithPow2Alignment(
SelectInst &SI,
2984 Value *XBiasedHighBits =
SI.getFalseValue();
2997 const APInt *LowBitMaskCst;
3002 const APInt *BiasCst, *HighBitMaskCst;
3003 if (!
match(XBiasedHighBits,
3006 !
match(XBiasedHighBits,
3011 if (!LowBitMaskCst->
isMask())
3014 APInt InvertedLowBitMaskCst = ~*LowBitMaskCst;
3015 if (InvertedLowBitMaskCst != *HighBitMaskCst)
3018 APInt AlignmentCst = *LowBitMaskCst + 1;
3020 if (*BiasCst != AlignmentCst && *BiasCst != *LowBitMaskCst)
3025 if (*BiasCst == *LowBitMaskCst &&
impliesPoison(XBiasedHighBits,
X))
3026 return XBiasedHighBits;
3031 Type *Ty =
X->getType();
3032 Value *XOffset = Builder.
CreateAdd(
X, ConstantInt::get(Ty, *LowBitMaskCst),
3033 X->getName() +
".biased");
3034 Value *
R = Builder.
CreateAnd(XOffset, ConstantInt::get(Ty, *HighBitMaskCst));
3040struct DecomposedSelect {
3052foldSelectOfSymmetricSelect(
SelectInst &OuterSelVal,
3055 Value *OuterCond, *InnerCond, *InnerTrueVal, *InnerFalseVal;
3083 DecomposedSelect OuterSel;
3090 std::swap(OuterSel.TrueVal, OuterSel.FalseVal);
3098 Value *InnerSelVal = IsAndVariant ? OuterSel.FalseVal : OuterSel.TrueVal;
3102 [](
Value *V) {
return V->hasOneUse(); }))
3106 DecomposedSelect InnerSel;
3107 if (!
match(InnerSelVal,
3114 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
3116 Value *AltCond =
nullptr;
3117 auto matchOuterCond = [OuterSel, IsAndVariant, &AltCond](
auto m_InnerCond) {
3122 return IsAndVariant ?
match(OuterSel.Cond,
3132 if (matchOuterCond(
m_Specific(InnerSel.Cond))) {
3137 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
3138 InnerSel.Cond = NotInnerCond;
3143 AltCond, IsAndVariant ? OuterSel.TrueVal : InnerSel.FalseVal,
3144 IsAndVariant ? InnerSel.TrueVal : OuterSel.FalseVal);
3147 IsAndVariant ? SelInner : InnerSel.TrueVal,
3148 !IsAndVariant ? SelInner : InnerSel.FalseVal);
3152 Value *CondVal =
SI.getCondition();
3155 Type *SelType =
SI.getType();
3174 return BinaryOperator::CreateOr(CondVal, FalseVal);
3184 if (
auto *LHS = dyn_cast<FCmpInst>(CondVal))
3185 if (
auto *RHS = dyn_cast<FCmpInst>(FalseVal))
3186 if (
Value *V = foldLogicOfFCmps(LHS, RHS,
false,
3194 bool CondLogicAnd = isa<SelectInst>(CondVal);
3195 bool FalseLogicAnd = isa<SelectInst>(FalseVal);
3196 auto AndFactorization = [&](
Value *Common,
Value *InnerCond,
3202 if (FalseLogicAnd || (CondLogicAnd && Common ==
A))
3205 return BinaryOperator::CreateAnd(Common, InnerSel);
3209 return AndFactorization(
A,
B,
D);
3211 return AndFactorization(
A,
B,
C);
3213 return AndFactorization(
B,
A,
D);
3215 return AndFactorization(
B,
A,
C, CondLogicAnd && FalseLogicAnd);
3222 return BinaryOperator::CreateAnd(CondVal, TrueVal);
3232 if (
auto *LHS = dyn_cast<FCmpInst>(CondVal))
3233 if (
auto *RHS = dyn_cast<FCmpInst>(TrueVal))
3234 if (
Value *V = foldLogicOfFCmps(LHS, RHS,
true,
3242 bool CondLogicOr = isa<SelectInst>(CondVal);
3243 bool TrueLogicOr = isa<SelectInst>(TrueVal);
3244 auto OrFactorization = [&](
Value *Common,
Value *InnerCond,
3250 if (TrueLogicOr || (CondLogicOr && Common ==
A))
3253 return BinaryOperator::CreateOr(Common, InnerSel);
3257 return OrFactorization(
A,
B,
D);
3259 return OrFactorization(
A,
B,
C);
3261 return OrFactorization(
B,
A,
D);
3263 return OrFactorization(
B,
A,
C, CondLogicOr && TrueLogicOr);
3306 return BinaryOperator::CreateXor(
A,
B);
3340 auto *FI =
new FreezeInst(*
Y, (*Y)->getName() +
".fr");
3346 if (
auto *ICmp0 = dyn_cast<ICmpInst>(CondVal))
3347 if (
auto *ICmp1 = dyn_cast<ICmpInst>(Op1))
3348 if (
auto *V = foldAndOrOfICmps(ICmp0, ICmp1, SI, IsAnd,
3359 if (Res && *Res ==
false)
3365 if (Res && *Res ==
false)
3374 if (Res && *Res ==
true)
3380 if (Res && *Res ==
true)
3393 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3394 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3395 bool MayNeedFreeze = SelCond && SelFVal &&
3396 match(SelFVal->getTrueValue(),
3409 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3410 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3411 bool MayNeedFreeze = SelCond && SelFVal &&
3412 match(SelCond->getTrueValue(),
3428 bool &ShouldDropNUW) {
3451 ShouldDropNUW =
false;
3457 auto MatchForward = [&](
Value *CommonAncestor) {
3458 const APInt *
C =
nullptr;
3459 if (CtlzOp == CommonAncestor)
3466 ShouldDropNUW =
true;
3477 const APInt *
C =
nullptr;
3478 Value *CommonAncestor;
3479 if (MatchForward(Cond0)) {
3483 if (!MatchForward(CommonAncestor))
3520 Type *SelType =
SI.getType();
3527 Value *Cond0, *Ctlz, *CtlzOp;
3543 !isSafeToRemoveBitCeilSelect(Pred, Cond0, Cond1, CtlzOp,
BitWidth,
3548 cast<Instruction>(CtlzOp)->setHasNoUnsignedWrap(
false);
3567 Value *TV =
SI.getTrueValue();
3568 Value *FV =
SI.getFalseValue();
3591 bool Replace =
false;
3625 FastMathFlags FMF = cast<FPMathOperator>(TrueVal)->getFastMathFlags();
3647 if (
auto *
I = dyn_cast<Instruction>(V)) {
3648 if (isa<PHINode>(
I)) {
3654 return Op->getType()->isIntOrIntVectorTy() &&
3655 hasAffectedValue(Op, Affected, Depth + 1);
3663 Value *CondVal =
SI.getCondition();
3666 Type *SelType =
SI.getType();
3675 if (
Instruction *
I = canonicalizeScalarSelectOfVecs(SI, *
this))
3711 return new ZExtInst(CondVal, SelType);
3715 return new SExtInst(CondVal, SelType);
3720 return new ZExtInst(NotCond, SelType);
3726 return new SExtInst(NotCond, SelType);
3730 auto *SIFPOp = dyn_cast<FPMathOperator>(&SI);
3732 if (
auto *FCmp = dyn_cast<FCmpInst>(CondVal)) {
3734 Value *Cmp0 = FCmp->getOperand(0), *Cmp1 = FCmp->getOperand(1);
3736 if ((Cmp0 == TrueVal && Cmp1 == FalseVal) ||
3737 (Cmp0 == FalseVal && Cmp1 == TrueVal)) {
3749 FCmp->getName() +
".inv");
3769 Value *MatchCmp0 =
nullptr;
3770 Value *MatchCmp1 =
nullptr;
3782 if (Cmp0 == MatchCmp0 &&
3783 matchFMulByZeroIfResultEqZero(*
this, Cmp0, Cmp1, MatchCmp1, MatchCmp0,
3784 SI, SIFPOp->hasNoSignedZeros()))
3794 if (SIFPOp->hasNoNaNs() && SIFPOp->hasNoSignedZeros()) {
3807 if (
Instruction *Fabs = foldSelectWithFCmpToFabs(SI, *
this))
3811 if (
ICmpInst *ICI = dyn_cast<ICmpInst>(CondVal))
3825 auto *TI = dyn_cast<Instruction>(TrueVal);
3826 auto *FI = dyn_cast<Instruction>(FalseVal);
3827 if (TI && FI && TI->getOpcode() == FI->
getOpcode())
3846 if (isa<VectorType>(CondVal->
getType()) && !isa<VectorType>(
Idx->getType()))
3858 if (
auto *TrueGep = dyn_cast<GetElementPtrInst>(TrueVal))
3859 if (
auto *NewGep = SelectGepWithBase(TrueGep, FalseVal,
false))
3861 if (
auto *FalseGep = dyn_cast<GetElementPtrInst>(FalseVal))
3862 if (
auto *NewGep = SelectGepWithBase(FalseGep, TrueVal,
true))
3878 RHS2, SI, SPF, RHS))
3882 RHS2, SI, SPF, LHS))
3891 bool IsCastNeeded =
LHS->
getType() != SelType;
3892 Value *CmpLHS = cast<CmpInst>(CondVal)->getOperand(0);
3893 Value *CmpRHS = cast<CmpInst>(CondVal)->getOperand(1);
3896 ((CmpLHS != LHS && CmpLHS != RHS) ||
3897 (CmpRHS != LHS && CmpRHS != RHS)))) {
3906 cast<FPMathOperator>(
SI.getCondition())->getFastMathFlags();
3922 if (
auto *PN = dyn_cast<PHINode>(
SI.getCondition()))
3924 if (canSelectOperandBeMappingIntoPredBlock(TrueVal, SI) &&
3925 canSelectOperandBeMappingIntoPredBlock(FalseVal, SI))
3929 if (
SelectInst *TrueSI = dyn_cast<SelectInst>(TrueVal)) {
3930 if (TrueSI->getCondition()->getType() == CondVal->
getType()) {
3933 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(
3934 *TrueSI, CondVal,
true,
DL))
3941 if (TrueSI->getFalseValue() == FalseVal && TrueSI->hasOneUse()) {
3949 if (
SelectInst *FalseSI = dyn_cast<SelectInst>(FalseVal)) {
3950 if (FalseSI->getCondition()->getType() == CondVal->
getType()) {
3953 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(
3954 *FalseSI, CondVal,
false,
DL))
3958 if (FalseSI->getTrueValue() == TrueVal && FalseSI->hasOneUse()) {
3975 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(0))) {
3976 if (TrueBOSI->getCondition() == CondVal) {
3982 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(1))) {
3983 if (TrueBOSI->getCondition() == CondVal) {
3994 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(0))) {
3995 if (FalseBOSI->getCondition() == CondVal) {
4001 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(1))) {
4002 if (FalseBOSI->getCondition() == CondVal) {
4015 SI.swapProfMetadata();
4030 if (Known.One.isOne())
4032 if (Known.Zero.isOne())
4040 if (
Value *V = foldSelectCmpXchg(SI))
4058 if (
Value *V = foldRoundUpIntegerWithPow2Alignment(SI,
Builder))
4068 auto *MaskedInst = cast<IntrinsicInst>(TrueVal);
4069 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
4070 MaskedInst->setArgOperand(3, FalseVal );
4085 bool CanMergeSelectIntoLoad =
false;
4089 if (CanMergeSelectIntoLoad) {
4090 auto *MaskedInst = cast<IntrinsicInst>(FalseVal);
4091 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
4092 MaskedInst->setArgOperand(3, TrueVal );
4121 auto FoldSelectWithAndOrCond = [&](
bool IsAnd,
Value *
A,
4129 if (
ICmpInst *Cmp = dyn_cast<ICmpInst>(
B))
4130 if (
Value *V = canonicalizeSPF(*Cmp, TrueVal, FalseVal, *
this))
4132 IsAnd ? FalseVal : V);
4140 if (
Instruction *
I = FoldSelectWithAndOrCond(
true, LHS, RHS))
4142 if (
Instruction *
I = FoldSelectWithAndOrCond(
true, RHS, LHS))
4145 if (
Instruction *
I = FoldSelectWithAndOrCond(
false, LHS, RHS))
4147 if (
Instruction *
I = FoldSelectWithAndOrCond(
false, RHS, LHS))
4153 if (
Instruction *
I = FoldSelectWithAndOrCond(
true, LHS, RHS))
4156 if (
Instruction *
I = FoldSelectWithAndOrCond(
false, LHS, RHS))
4163 return BinaryOperator::CreateXor(CondVal, FalseVal);
4168 (!isa<Constant>(TrueVal) || !isa<Constant>(FalseVal))) {
4172 CC.AffectedValues.insert(V);
4175 if (!
CC.AffectedValues.empty()) {
4176 if (!isa<Constant>(TrueVal) &&
4177 hasAffectedValue(TrueVal,
CC.AffectedValues, 0)) {
4185 if (!isa<Constant>(FalseVal) &&
4186 hasAffectedValue(FalseVal,
CC.AffectedValues, 0)) {
SmallVector< AArch64_IMM::ImmInsnModel, 4 > Insn
amdgpu AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
This file provides internal interfaces used to implement the InstCombine.
static Value * canonicalizeSaturatedAdd(ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
static Instruction * foldSetClearBits(SelectInst &Sel, InstCombiner::BuilderTy &Builder)
Canonicalize a set or clear of a masked set of constant bits to select-of-constants form.
static Instruction * foldSelectICmpAndAnd(Type *SelType, const ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
We want to turn: (select (icmp eq (and X, Y), 0), (and (lshr X, Z), 1), 1) into: zext (icmp ne i32 (a...
static unsigned getSelectFoldableOperands(BinaryOperator *I)
We want to turn code that looks like this: C = or A, B D = select cond, C, A into: C = select cond,...
static Instruction * foldSelectZeroOrMul(SelectInst &SI, InstCombinerImpl &IC)
static Value * canonicalizeSaturatedSubtract(const ICmpInst *ICI, const Value *TrueVal, const Value *FalseVal, InstCombiner::BuilderTy &Builder)
Transform patterns such as (a > b) ? a - b : 0 into usub.sat(a, b).
static Value * foldAbsDiff(ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
Try to match patterns with select and subtract as absolute difference.
static Instruction * foldSelectBinOpIdentity(SelectInst &Sel, const TargetLibraryInfo &TLI, InstCombinerImpl &IC)
Replace a select operand based on an equality comparison with the identity constant of a binop.
static Value * foldSelectICmpAndZeroShl(const ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
We want to turn: (select (icmp eq (and X, C1), 0), 0, (shl [nsw/nuw] X, C2)); iff C1 is a mask and th...
static Value * foldSelectICmpAndBinOp(const ICmpInst *IC, Value *TrueVal, Value *FalseVal, InstCombiner::BuilderTy &Builder)
We want to turn: (select (icmp eq (and X, C1), 0), Y, (BinOp Y, C2)) into: IF C2 u>= C1 (BinOp Y,...
static Value * foldSelectICmpLshrAshr(const ICmpInst *IC, Value *TrueVal, Value *FalseVal, InstCombiner::BuilderTy &Builder)
We want to turn: (select (icmp sgt x, C), lshr (X, Y), ashr (X, Y)); iff C s>= -1 (select (icmp slt x...
static bool isSelect01(const APInt &C1I, const APInt &C2I)
static Value * foldSelectICmpAnd(SelectInst &Sel, ICmpInst *Cmp, InstCombiner::BuilderTy &Builder)
This folds: select (icmp eq (and X, C1)), TC, FC iff C1 is a power 2 and the difference between TC an...
This file provides the interface for the instcombine pass implementation.
uint64_t IntrinsicInst * II
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static const uint32_t IV[8]
bool bitwiseIsEqual(const APFloat &RHS) const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
bool isMinSignedValue() const
Determine if this is the smallest signed value.
uint64_t getZExtValue() const
Get zero extended value.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
unsigned getBitWidth() const
Return the number of bits in the APInt.
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
bool isMinValue() const
Determine if this is the smallest unsigned value.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
unsigned countLeadingZeros() const
unsigned logBase2() const
bool isMask(unsigned numBits) const
bool isMaxSignedValue() const
Determine if this is the largest signed value.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
bool isOne() const
Determine if this is a value of 1.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
bool isMaxValue() const
Determine if this is the largest unsigned value.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
MutableArrayRef< ResultElem > assumptions()
Access the list of assumption handles currently tracked for this function.
An instruction that atomically checks whether a specified value is in a memory location,...
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
BinaryOps getOpcode() const
static BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
static BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
This class represents a no-op cast from one type to another.
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ ICMP_ULT
unsigned less than
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
bool isFPPredicate() const
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Predicate getPredicate() const
Return the predicate for this instruction.
static bool isUnordered(Predicate predicate)
Determine if the predicate is an unordered operation.
Predicate getFlippedStrictnessPredicate() const
For predicate of kind "is X or equal to 0" returns the predicate "is X".
bool isIntPredicate() const
static Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)
Return the identity constant for a binary opcode.
static Constant * getNeg(Constant *C, bool HasNSW=false)
static ConstantInt * getTrue(LLVMContext &Context)
static ConstantInt * getFalse(LLVMContext &Context)
This class represents a range of values.
ConstantRange add(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an addition of a value in this ran...
bool icmp(CmpInst::Predicate Pred, const ConstantRange &Other) const
Does the predicate Pred hold between ranges this and Other? NOTE: false does not mean that inverse pr...
static ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)
Produce the exact range such that all values in the returned range satisfy the given predicate with a...
ConstantRange binaryNot() const
Return a new range representing the possible values resulting from a binary-xor of a value in this ra...
ConstantRange binaryOp(Instruction::BinaryOps BinOp, const ConstantRange &Other) const
Return a new range representing the possible values resulting from an application of the specified bi...
ConstantRange sub(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a subtraction of a value in this r...
This is an important base class in LLVM.
static Constant * mergeUndefsWith(Constant *C, Constant *Other)
Merges undefs of a Constant with another Constant, along with the undefs already present.
static Constant * getAllOnesValue(Type *Ty)
bool isOneValue() const
Returns true if the value is one.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
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.
bool noSignedZeros() const
void setNoSignedZeros(bool B=true)
This class represents a freeze function that returns random concrete value if an operand is either a ...
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Value * getPointerOperand()
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Type * getSourceElementType() const
GEPNoWrapFlags getNoWrapFlags() const
Get the nowrap flags for the GEP instruction.
uint64_t getType(const MachineInstr &MI) const
This instruction compares its operands according to the predicate given to the constructor.
static bool isLT(Predicate P)
Return true if the predicate is SLT or ULT.
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.
Common base class shared among various IRBuilders.
CallInst * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with 1 operand which is mangled on its type.
Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with 2 operands which is mangled on the first type.
Value * CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")
Return a vector value that contains.
ConstantInt * getTrue()
Get the constant value for i1 true.
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
Value * CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Value * CreateFreeze(Value *V, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
void setFastMathFlags(FastMathFlags NewFMF)
Set the fast-math flags to be used with generated fp-math operators.
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateIsNeg(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg < 0.
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateLogicalAnd(Value *Cond1, Value *Cond2, const Twine &Name="")
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="")
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateLogicalOr(Value *Cond1, Value *Cond2, const Twine &Name="")
Value * CreateFNeg(Value *V, const Twine &Name="", MDNode *FPMathTag=nullptr)
Instruction * foldSelectToCmp(SelectInst &SI)
bool fmulByZeroIsZero(Value *MulVal, FastMathFlags FMF, const Instruction *CtxI) const
Check if fmul MulVal, +0.0 will yield +0.0 (or signed zero is ignorable).
KnownFPClass computeKnownFPClass(Value *Val, FastMathFlags FMF, FPClassTest Interested=fcAllFlags, const Instruction *CtxI=nullptr, unsigned Depth=0) const
Instruction * foldOpIntoPhi(Instruction &I, PHINode *PN)
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 * foldSelectValueEquivalence(SelectInst &SI, ICmpInst &ICI)
Instruction * foldSPFofSPF(Instruction *Inner, SelectPatternFlavor SPF1, Value *A, Value *B, Instruction &Outer, SelectPatternFlavor SPF2, Value *C)
Instruction * foldSelectOpOp(SelectInst &SI, Instruction *TI, Instruction *FI)
We have (select c, TI, FI), and we know that TI and FI have the same opcode.
bool replaceInInstruction(Value *V, Value *Old, Value *New, unsigned Depth=0)
Instruction * foldSelectInstWithICmp(SelectInst &SI, ICmpInst *ICI)
bool sinkNotIntoOtherHandOfLogicalOp(Instruction &I)
Constant * getLosslessTrunc(Constant *C, Type *TruncTy, unsigned ExtOp)
Instruction * foldSelectIntoOp(SelectInst &SI, Value *, Value *)
Try to fold the select into one of the operands to allow further optimization.
Instruction * visitSelectInst(SelectInst &SI)
Instruction * foldSelectOfBools(SelectInst &SI)
Instruction * foldSelectExtConst(SelectInst &Sel)
The core instruction combiner logic.
const DataLayout & getDataLayout() const
static bool isCanonicalPredicate(CmpInst::Predicate Pred)
Predicate canonicalization reduces the number of patterns that need to be matched by other transforms...
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, unsigned Depth=0, const Instruction *CxtI=nullptr)
Instruction * InsertNewInstBefore(Instruction *New, BasicBlock::iterator Old)
Inserts an instruction New before instruction Old.
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
static bool shouldAvoidAbsorbingNotIntoSelect(const SelectInst &SI)
static std::optional< std::pair< CmpInst::Predicate, Constant * > > getFlippedStrictnessPredicateAndConstant(CmpInst::Predicate Pred, Constant *C)
void replaceUse(Use &U, Value *NewValue)
Replace use and add the previously used value to the worklist.
InstructionWorklist & Worklist
A worklist of the instructions that need to be simplified.
void addToWorklist(Instruction *I)
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth, const Instruction *CxtI) const
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
const SimplifyQuery & getSimplifyQuery() const
static Constant * AddOne(Constant *C)
Add one to a Constant.
void add(Instruction *I)
Add instruction to the worklist.
void push(Instruction *I)
Push the instruction onto the worklist stack.
bool 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.
bool hasNoSignedZeros() const LLVM_READONLY
Determine whether the no-signed-zeros flag is set.
void copyIRFlags(const Value *V, bool IncludeWrapFlags=true)
Convenience method to copy supported exact, fast-math, and (optionally) wrapping flags from V to this...
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction.
bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
void swapProfMetadata()
If the instruction has "branch_weights" MD_prof metadata and the MDNode has three operands (including...
FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void dropPoisonGeneratingFlags()
Drops flags that may cause this instruction to evaluate to poison despite having non-poison inputs.
const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
A wrapper class for inspecting calls to intrinsic functions.
A Module instance is used to store all the information related to an LLVM module.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
This class represents a sign extension of integer types.
This class represents the LLVM 'select' instruction.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, Instruction *MDFrom=nullptr)
const Value * getFalseValue() const
void swapValues()
Swap the true and false values of the select instruction.
const Value * getCondition() const
const Value * getTrueValue() const
bool insert(const value_type &X)
Insert a new element into the SetVector.
This instruction constructs a fixed permutation of two input vectors.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool contains(ConstPtrType Ptr) const
A SetVector that performs no allocations if smaller than a certain size.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Provides information about what library functions are available for the current target.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
static IntegerType * getInt1Ty(LLVMContext &C)
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
static UnaryOperator * CreateFNegFMF(Value *Op, Instruction *FMFSource, const Twine &Name="", InsertPosition InsertBefore=nullptr)
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
const Value * DoPHITranslation(const BasicBlock *CurBB, const BasicBlock *PredBB) const
Translate PHI node to its predecessor from the given basic block.
bool hasOneUse() const
Return true if there is exactly one use of this value.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
Represents an op.with.overflow intrinsic.
This class represents zero extension of integer types.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
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.
BinaryOp_match< LHS, RHS, Instruction::FMul, true > m_c_FMul(const LHS &L, const RHS &R)
Matches FMul with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FSub > m_FSub(const LHS &L, const RHS &R)
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power-of-2.
match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
SpecificCmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate, true > m_c_SpecificICmp(ICmpInst::Predicate MatchPred, const LHS &L, const RHS &R)
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
match_combine_or< CastInst_match< OpTy, ZExtInst >, OpTy > m_ZExtOrSelf(const OpTy &Op)
bool match(Val *V, const Pattern &P)
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
constantexpr_match m_ConstantExpr()
Match a constant expression or a constant that contains a constant expression.
specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)
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.
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.
CmpClass_match< LHS, RHS, FCmpInst, FCmpInst::Predicate > m_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R)
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.
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
cst_pred_ty< is_zero_int > m_ZeroInt()
Match an integer 0 or a vector with all elements equal to 0.
apint_match m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate > m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)
OneUse_match< T > m_OneUse(const T &SubPattern)
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
BinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub > m_Neg(const ValTy &V)
Matches a 'Neg' as 'sub 0, V'.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
match_combine_and< class_match< Constant >, match_unless< constantexpr_match > > m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2, Opnd3 >::Ty m_MaskedLoad(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2, const Opnd3 &Op3)
Matches MaskedLoad Intrinsic.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
BinOpPred_match< LHS, RHS, is_bitwiselogic_op, true > m_c_BitwiseLogic(const LHS &L, const RHS &R)
Matches bitwise logic operations in either order.
MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty > m_UMax(const LHS &L, const RHS &R)
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
auto m_c_LogicalOp(const LHS &L, const RHS &R)
Matches either L && R or L || R with LHS and RHS in either order.
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate, true > m_c_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
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.
SpecificCmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate > m_SpecificICmp(ICmpInst::Predicate MatchPred, const LHS &L, const RHS &R)
CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty > m_SMax(const LHS &L, const RHS &R)
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
MaxMin_match< FCmpInst, LHS, RHS, ofmax_pred_ty > m_OrdFMax(const LHS &L, const RHS &R)
Match an 'ordered' floating point maximum function.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
AnyBinaryOp_match< LHS, RHS, true > m_c_BinOp(const LHS &L, const RHS &R)
Matches a BinaryOperator with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
cstfp_pred_ty< is_pos_zero_fp > m_PosZeroFP()
Match a floating-point positive zero.
LogicalOp_match< LHS, RHS, Instruction::And, true > m_c_LogicalAnd(const LHS &L, const RHS &R)
Matches L && R with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
m_Intrinsic_Ty< Opnd0 >::Ty m_VecReverse(const Opnd0 &Op0)
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
MaxMin_match< FCmpInst, LHS, RHS, ofmin_pred_ty > m_OrdFMin(const LHS &L, const RHS &R)
Match an 'ordered' floating point minimum function.
match_combine_or< match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty >, MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > >, match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty >, MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > > > m_MaxOrMin(const LHS &L, const RHS &R)
class_match< BasicBlock > m_BasicBlock()
Match an arbitrary basic block value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)
auto m_Undef()
Match an arbitrary undef constant.
BinaryOp_match< cst_pred_ty< is_all_ones >, ValTy, Instruction::Xor, true > m_Not(const ValTy &V)
Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
BinOpPred_match< LHS, RHS, is_bitwiselogic_op > m_BitwiseLogic(const LHS &L, const RHS &R)
Matches bitwise logic operations.
LogicalOp_match< LHS, RHS, Instruction::Or, true > m_c_LogicalOr(const LHS &L, const RHS &R)
Matches L || R with LHS and RHS in either order.
ElementWiseBitCast_match< OpTy > m_ElementWiseBitCast(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > m_UMin(const LHS &L, const RHS &R)
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2, Opnd3 >::Ty m_MaskedGather(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2, const Opnd3 &Op3)
Matches MaskedGather Intrinsic.
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
cst_pred_ty< icmp_pred_with_threshold > m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold)
Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.
ElementType
The element type of an SRV or UAV resource.
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
bool isSafeToSpeculativelyExecuteWithVariableReplaced(const Instruction *I)
Don't use information from its non-constant operands.
bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS, bool &TrueIfSigned)
Given an exploded icmp instruction, return true if the comparison only checks the sign bit.
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Instruction *I=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
CmpInst::Predicate getMinMaxPred(SelectPatternFlavor SPF, bool Ordered=false)
Return the canonical comparison predicate for the specified minimum/maximum flavor.
bool isGuaranteedNotToBeUndef(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be undef, but may be poison.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)
Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...
constexpr unsigned MaxAnalysisRecursionDepth
SelectPatternFlavor
Specific patterns of select instructions we can match.
@ SPF_ABS
Floating point maxnum.
@ SPF_NABS
Absolute value.
@ SPF_UMIN
Signed minimum.
@ SPF_UMAX
Signed maximum.
@ SPF_SMAX
Unsigned minimum.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool impliesPoison(const Value *ValAssumedPoison, const Value *V)
Return true if V is poison given that ValAssumedPoison is already poison.
SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)
Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind and providing the out param...
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
Value * simplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an And, fold the result or return null.
bool isKnownInversion(const Value *X, const Value *Y)
Return true iff:
Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
constexpr int PoisonMaskElem
@ 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.
void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
DWARFExpression::Operation Op
constexpr unsigned BitWidth
SelectPatternResult matchDecomposedSelectPattern(CmpInst *CmpI, Value *TrueVal, Value *FalseVal, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)
Determine the pattern that a select with the given compare as its predicate and given values as its t...
Value * simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp, const SimplifyQuery &Q, bool AllowRefinement, SmallVectorImpl< Instruction * > *DropFlags=nullptr)
See if V simplifies when its operand Op is replaced with RepOp.
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
bool decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate &Pred, Value *&X, APInt &Mask, bool LookThroughTrunc=true)
Decompose an icmp into the form ((X & Mask) pred 0) if possible.
bool cannotBeNegativeZero(const Value *V, unsigned Depth, const SimplifyQuery &SQ)
Return true if we can prove that the specified FP value is never equal to -0.0.
bool isKnownNeverNaN(const Value *V, unsigned Depth, const SimplifyQuery &SQ)
Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...
bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
bool isCheckForZeroAndMulWithOverflow(Value *Op0, Value *Op1, bool IsAnd, Use *&Y)
Match one of the patterns up to the select/logic op: Op0 = icmp ne i4 X, 0 Agg = call { i4,...
Value * simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, const SimplifyQuery &Q)
Given operands for a SelectInst, fold the result or return null.
std::optional< bool > isImpliedCondition(const Value *LHS, const Value *RHS, const DataLayout &DL, bool LHSIsTrue=true, unsigned Depth=0)
Return true if RHS is known to be implied true by LHS.
void findValuesAffectedByCondition(Value *Cond, bool IsAssume, function_ref< void(Value *)> InsertAffected)
Call InsertAffected on all Values whose known bits / value may be affected by the condition Cond.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Evaluate query assuming this condition holds.
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...
bool isConstant() const
Returns true if we know the value of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
bool isKnownNeverInfinity() const
Return true if it's known this can never be an infinity.
bool isKnownNeverNaN() const
Return true if it's known this can never be a nan.
bool signBitIsZeroOrNaN() const
Return true if the sign bit must be 0, ignoring the sign of nans.
SelectPatternFlavor Flavor
bool Ordered
Only applicable if Flavor is SPF_FMINNUM or SPF_FMAXNUM.
static bool isMinOrMax(SelectPatternFlavor SPF)
When implementing this min/max pattern as fcmp; select, does the fcmp have to be ordered?
SimplifyQuery getWithCondContext(const CondContext &CC) const
SimplifyQuery getWithInstruction(const Instruction *I) const