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);
165 if (!TC.
isZero() && !FC.isZero()) {
174 if (!Cmp->hasOneUse())
176 V = Builder.
CreateAnd(V, ConstantInt::get(SelType, AndMask));
178 bool ExtraBitInTC = TC.
ugt(FC);
179 if (Pred == ICmpInst::ICMP_EQ) {
183 Constant *
C = ConstantInt::get(SelType, TC);
186 if (Pred == ICmpInst::ICMP_NE) {
190 Constant *
C = ConstantInt::get(SelType, FC);
203 unsigned ValZeros = ValC.
logBase2();
204 unsigned AndZeros = AndMask.
logBase2();
208 V = Builder.
CreateAnd(V, ConstantInt::get(V->getType(), AndMask));
212 if (ValZeros > AndZeros) {
214 V = Builder.
CreateShl(V, ValZeros - AndZeros);
215 }
else if (ValZeros < AndZeros) {
216 V = Builder.
CreateLShr(V, AndZeros - ValZeros);
224 bool ShouldNotVal = !TC.
isZero();
225 ShouldNotVal ^= Pred == ICmpInst::ICMP_NE;
243 switch (
I->getOpcode()) {
244 case Instruction::Add:
245 case Instruction::FAdd:
246 case Instruction::Mul:
247 case Instruction::FMul:
248 case Instruction::And:
249 case Instruction::Or:
250 case Instruction::Xor:
252 case Instruction::Sub:
253 case Instruction::FSub:
254 case Instruction::FDiv:
255 case Instruction::Shl:
256 case Instruction::LShr:
257 case Instruction::AShr:
287 if (
auto *CondVTy = dyn_cast<VectorType>(CondTy)) {
289 CondVTy->getElementCount() !=
290 cast<VectorType>(FIOpndTy)->getElementCount())
301 if (TI->
getOpcode() != Instruction::BitCast &&
314 SI.getName() +
".v", &SI);
319 Value *OtherOpT, *OtherOpF;
322 bool Swapped =
false) ->
Value * {
323 assert(!(Commute && Swapped) &&
324 "Commute and Swapped can't set at the same time");
329 MatchIsOpZero =
true;
334 MatchIsOpZero =
false;
339 if (!Commute && !Swapped)
348 MatchIsOpZero =
true;
353 MatchIsOpZero =
false;
367 FMF |= SI.getFastMathFlags();
370 if (
auto *NewSelI = dyn_cast<Instruction>(NewSel))
371 NewSelI->setFastMathFlags(FMF);
372 Instruction *NewFNeg = UnaryOperator::CreateFNeg(NewSel);
381 auto *
TII = dyn_cast<IntrinsicInst>(TI);
382 auto *FII = dyn_cast<IntrinsicInst>(FI);
383 if (
TII && FII &&
TII->getIntrinsicID() == FII->getIntrinsicID()) {
385 if (
Value *MatchOp = getCommonOp(TI, FI,
true)) {
397 if (
TII->getIntrinsicID() == Intrinsic::ldexp) {
398 Value *LdexpVal0 =
TII->getArgOperand(0);
399 Value *LdexpExp0 =
TII->getArgOperand(1);
400 Value *LdexpVal1 = FII->getArgOperand(0);
401 Value *LdexpExp1 = FII->getArgOperand(1);
405 FMF &= cast<FPMathOperator>(FII)->getFastMathFlags();
412 TII->
getType(), Intrinsic::ldexp, {SelectVal, SelectExp});
425 bool Swapped = TPred != FPred;
429 SI.getName() +
".v", &SI);
444 (!isa<BinaryOperator>(TI) && !isa<GetElementPtrInst>(TI)) ||
466 auto *BO = dyn_cast<BinaryOperator>(TI);
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;
480 if (
auto *BO = dyn_cast<BinaryOperator>(TI)) {
486 if (
auto *TGEP = dyn_cast<GetElementPtrInst>(TI)) {
487 auto *FGEP = cast<GetElementPtrInst>(FI);
488 Type *ElementType = TGEP->getResultElementType();
489 return TGEP->isInBounds() && FGEP->isInBounds()
512 auto *TVI = dyn_cast<BinaryOperator>(TrueVal);
513 if (!TVI || !TVI->hasOneUse() || isa<Constant>(FalseVal))
517 unsigned OpToFold = 0;
518 if ((SFO & 1) && FalseVal == TVI->getOperand(0))
520 else if ((SFO & 2) && FalseVal == TVI->getOperand(1))
530 if (isa<FPMathOperator>(&SI))
531 FMF = SI.getFastMathFlags();
533 TVI->getOpcode(), TVI->getType(),
true, FMF.
noSignedZeros());
534 Value *OOp = TVI->getOperand(2 - OpToFold);
539 if (isa<Constant>(OOp) &&
540 (!OOpIsAPInt || !
isSelect01(
C->getUniqueInteger(), *OOpC)))
549 if (isa<FPMathOperator>(&SI) &&
554 Swapped ? OOp :
C,
"", &SI);
555 if (isa<FPMathOperator>(&SI))
556 cast<Instruction>(NewSel)->setFastMathFlags(FMF);
564 if (
Instruction *R = TryFoldSelectIntoOp(SI, TrueVal, FalseVal,
false))
567 if (
Instruction *R = TryFoldSelectIntoOp(SI, FalseVal, TrueVal,
true))
584 if (!(Cmp->hasOneUse() && Cmp->getOperand(0)->hasOneUse() &&
616 Constant *One = ConstantInt::get(SelType, 1);
621 return new ZExtInst(ICmpNeZero, SelType);
643 const APInt *C2, *C1;
653 auto *FI = dyn_cast<Instruction>(FVal);
657 FI->setHasNoSignedWrap(
false);
658 FI->setHasNoUnsignedWrap(
false);
693 const auto *Ashr = cast<Instruction>(FalseVal);
695 bool IsExact = Ashr->isExact() && cast<Instruction>(TrueVal)->isExact();
727 if (!TrueVal->getType()->isIntOrIntVectorTy() ||
762 BinOp = cast<BinaryOperator>(FalseVal);
766 BinOp = cast<BinaryOperator>(TrueVal);
776 if (IdentityC ==
nullptr || !IdentityC->isNullValue())
781 bool NeedShift = C1Log != C2Log;
782 bool NeedZExtTrunc =
Y->getType()->getScalarSizeInBits() !=
783 V->getType()->getScalarSizeInBits();
786 if ((NeedShift + NeedXor + NeedZExtTrunc +
NeedAnd) >
793 V = Builder.
CreateAnd(V, ConstantInt::get(V->getType(), C1));
799 }
else if (C1Log > C2Log) {
826 Constant *OrC = ConstantInt::get(Ty, *
C);
828 return BinaryOperator::CreateOr(
T, NewSel);
835 Constant *OrC = ConstantInt::get(Ty, *
C);
837 return BinaryOperator::CreateOr(
F, NewSel);
854 auto *CondVal = SI.getCondition();
855 auto *TrueVal = SI.getTrueValue();
856 auto *FalseVal = SI.getFalseValue();
874 auto *TrueValC = dyn_cast<Constant>(TrueVal);
875 if (TrueValC ==
nullptr ||
877 !isa<Instruction>(FalseVal))
880 auto *ZeroC = cast<Constant>(cast<Instruction>(CondVal)->getOperand(1));
888 auto *FalseValI = cast<Instruction>(FalseVal);
891 IC.
replaceOperand(*FalseValI, FalseValI->getOperand(0) ==
Y ? 0 : 1, FrY);
899 const Value *TrueVal,
900 const Value *FalseVal,
921 ConstantInt::get(
A->getType(), 1));
935 "Unexpected isUnsigned predicate!");
941 bool IsNegative =
false;
954 if (IsNegative && !TrueVal->hasOneUse() && !ICI->
hasOneUse())
967 if (!Cmp->hasOneUse())
971 Value *Cmp0 = Cmp->getOperand(0);
972 Value *Cmp1 = Cmp->getOperand(1);
981 Intrinsic::uadd_sat,
X, ConstantInt::get(
X->getType(), *
C));
1038 auto *TI = dyn_cast<Instruction>(TVal);
1039 auto *FI = dyn_cast<Instruction>(FVal);
1045 Value *
A = Cmp->getOperand(0);
1046 Value *
B = Cmp->getOperand(1);
1059 (TI->hasNoSignedWrap() || TI->hasNoUnsignedWrap()) &&
1060 (FI->hasNoSignedWrap() || FI->hasNoUnsignedWrap())) {
1067 TI->setHasNoUnsignedWrap(
false);
1068 if (!TI->hasNoSignedWrap())
1069 TI->setHasNoSignedWrap(TI->hasOneUse());
1097 if (!
match(FalseVal,
1101 if (!
match(Ctlz, m_Intrinsic<Intrinsic::ctlz>()))
1108 auto *II = cast<IntrinsicInst>(Ctlz);
1145 Value *Count =
nullptr;
1153 if (!
match(Count, m_Intrinsic<Intrinsic::cttz>(
m_Value(
X))) &&
1189 if (!
TrueVal->getType()->isIntOrIntVectorTy())
1216 IntrinsicID = Intrinsic::umin;
1219 IntrinsicID = Intrinsic::umax;
1222 IntrinsicID = Intrinsic::smin;
1225 IntrinsicID = Intrinsic::smax;
1242 auto *
I = dyn_cast<Instruction>(V);
1246 bool Changed =
false;
1247 for (
Use &U :
I->operands()) {
1277 if (!
Cmp.isEquality())
1282 bool Swapped =
false;
1293 Value *CmpLHS =
Cmp.getOperand(0), *CmpRHS =
Cmp.getOperand(1);
1294 if (TrueVal != CmpLHS &&
1301 if (isa<Constant>(CmpRHS) || isa<Constant>(V))
1312 !
Cmp.getType()->isVectorTy())
1316 if (TrueVal != CmpRHS &&
1320 if (isa<Constant>(CmpLHS) || isa<Constant>(V))
1323 auto *FalseInst = dyn_cast<Instruction>(FalseVal);
1338 &DropFlags) == TrueVal ||
1341 &DropFlags) == TrueVal) {
1343 I->dropPoisonGeneratingAnnotations();
1384 if (!isa<SelectInst>(Sel1)) {
1425 if (Cmp00->
getType() !=
X->getType() &&
X->hasOneUse())
1433 else if (!
match(Cmp00,
1441 Value *ReplacementLow, *ReplacementHigh;
1478 std::swap(ReplacementLow, ReplacementHigh);
1484 "Unexpected predicate type.");
1492 "Unexpected predicate type.");
1494 std::swap(ThresholdLowIncl, ThresholdHighExcl);
1510 if (
X->getType() != Sel0.
getType()) {
1520 assert(ReplacementLow && ReplacementHigh &&
1521 "Constant folding of ImmConstant cannot fail");
1527 Value *MaybeReplacedLow =
1533 ShouldReplaceHigh, ReplacementHigh, MaybeReplacedLow);
1577 Value *SelVal0, *SelVal1;
1586 auto MatchesSelectValue = [SelVal0, SelVal1](
Constant *
C) {
1587 return C->isElementWiseEqual(SelVal0) ||
C->isElementWiseEqual(SelVal1);
1591 if (MatchesSelectValue(C0))
1595 auto FlippedStrictness =
1597 if (!FlippedStrictness)
1601 if (!MatchesSelectValue(FlippedStrictness->second))
1610 Cmp.getName() +
".inv");
1621 if (!
Cmp->hasOneUse())
1651 Value *TVal =
SI.getTrueValue();
1652 Value *FVal =
SI.getFalseValue();
1678 const APInt *BinOpC;
1715 const unsigned AndOps = Instruction::And, OrOps = Instruction::Or,
1716 XorOps = Instruction::Xor, NoOps = 0;
1717 enum NotMask {
None = 0, NotInner, NotRHS };
1719 auto matchFalseVal = [&](
unsigned OuterOpc,
unsigned InnerOpc,
1722 if (OuterOpc == NoOps)
1725 if (NotMask == NotInner) {
1728 }
else if (NotMask == NotRHS) {
1732 return match(FalseVal,
1743 if (matchFalseVal(OrOps, XorOps,
None) ||
1744 matchFalseVal(XorOps, XorOps,
None))
1749 if (matchFalseVal(XorOps, OrOps,
None) ||
1750 matchFalseVal(AndOps, OrOps, NotRHS))
1761 if (matchFalseVal(XorOps, XorOps,
None) ||
1762 matchFalseVal(AndOps, XorOps, NotInner))
1767 if (matchFalseVal(XorOps, AndOps,
None) ||
1768 matchFalseVal(AndOps, AndOps, NotInner))
1779 if (matchFalseVal(XorOps, OrOps,
None) ||
1780 matchFalseVal(AndOps, OrOps, NotRHS))
1785 if (matchFalseVal(OrOps, AndOps,
None) ||
1786 matchFalseVal(XorOps, AndOps,
None))
1801 canonicalizeSPF(*ICI,
SI.getTrueValue(),
SI.getFalseValue(), *
this))
1804 if (
Value *V = foldSelectInstWithICmpConst(SI, ICI,
Builder))
1807 if (
Value *V = canonicalizeClampLike(SI, *ICI,
Builder, *
this))
1811 tryToReuseConstantFromSelectInComparison(SI, *ICI, *
this))
1818 bool Changed =
false;
1824 if (CmpRHS != CmpLHS && isa<Constant>(CmpRHS) && !isa<Constant>(CmpLHS)) {
1836 if (
Instruction *NewSel = foldSelectICmpEq(SI, ICI, *
this))
1851 SI.swapProfMetadata();
1857 if (
TrueVal->getType()->isIntOrIntVectorTy()) {
1864 bool IsBitTest =
false;
1872 Y = &MinSignedValue;
1874 TrueWhenUnset =
false;
1877 Y = &MinSignedValue;
1879 TrueWhenUnset =
true;
1884 if (TrueWhenUnset && TrueVal ==
X &&
1888 else if (!TrueWhenUnset && FalseVal ==
X &&
1892 else if (TrueWhenUnset && FalseVal ==
X &&
1896 else if (!TrueWhenUnset && TrueVal ==
X &&
1924 if (
Value *V = foldSelectCttzCtlz(ICI, TrueVal, FalseVal,
Builder))
1936 return Changed ? &
SI :
nullptr;
1948static bool canSelectOperandBeMappingIntoPredBlock(
const Value *V,
1953 if (!
I)
return true;
1957 const PHINode *CondPHI = cast<PHINode>(
SI.getCondition());
1959 if (
const PHINode *VP = dyn_cast<PHINode>(
I))
1960 if (VP->getParent() == CondPHI->
getParent())
1984 if (
C ==
A ||
C ==
B) {
1999 Value *CondVal =
SI.getCondition();
2002 auto *TI = dyn_cast<Instruction>(TrueVal);
2003 auto *FI = dyn_cast<Instruction>(FalseVal);
2004 if (!TI || !FI || !TI->hasOneUse() || !FI->hasOneUse())
2008 if ((TI->getOpcode() == Instruction::Sub &&
2009 FI->getOpcode() == Instruction::Add) ||
2010 (TI->getOpcode() == Instruction::FSub &&
2011 FI->getOpcode() == Instruction::FAdd)) {
2014 }
else if ((FI->getOpcode() == Instruction::Sub &&
2015 TI->getOpcode() == Instruction::Add) ||
2016 (FI->getOpcode() == Instruction::FSub &&
2017 TI->getOpcode() == Instruction::FAdd)) {
2023 Value *OtherAddOp =
nullptr;
2024 if (SubOp->getOperand(0) == AddOp->
getOperand(0)) {
2026 }
else if (SubOp->getOperand(0) == AddOp->
getOperand(1)) {
2034 if (
SI.getType()->isFPOrFPVectorTy()) {
2035 NegVal = Builder.
CreateFNeg(SubOp->getOperand(1));
2036 if (
Instruction *NegInst = dyn_cast<Instruction>(NegVal)) {
2038 Flags &= SubOp->getFastMathFlags();
2039 NegInst->setFastMathFlags(Flags);
2042 NegVal = Builder.
CreateNeg(SubOp->getOperand(1));
2045 Value *NewTrueOp = OtherAddOp;
2046 Value *NewFalseOp = NegVal;
2050 SI.getName() +
".p", &SI);
2052 if (
SI.getType()->isFPOrFPVectorTy()) {
2054 BinaryOperator::CreateFAdd(SubOp->getOperand(0), NewSel);
2057 Flags &= SubOp->getFastMathFlags();
2061 return BinaryOperator::CreateAdd(SubOp->getOperand(0), NewSel);
2074 Value *CondVal =
SI.getCondition();
2086 auto IsSignedSaturateLimit = [&](
Value *Limit,
bool IsAdd) {
2096 auto IsZeroOrOne = [](
const APInt &
C) {
return C.isZero() ||
C.isOne(); };
2113 IsMinMax(TrueVal, FalseVal))
2120 IsMinMax(FalseVal, TrueVal))
2126 IsMinMax(TrueVal, FalseVal))
2131 IsMinMax(FalseVal, TrueVal))
2136 IsMinMax(FalseVal, TrueVal))
2141 IsMinMax(TrueVal, FalseVal))
2152 NewIntrinsicID = Intrinsic::uadd_sat;
2153 else if (II->
getIntrinsicID() == Intrinsic::usub_with_overflow &&
2156 NewIntrinsicID = Intrinsic::usub_sat;
2157 else if (II->
getIntrinsicID() == Intrinsic::sadd_with_overflow &&
2158 IsSignedSaturateLimit(TrueVal,
true))
2167 NewIntrinsicID = Intrinsic::sadd_sat;
2168 else if (II->
getIntrinsicID() == Intrinsic::ssub_with_overflow &&
2169 IsSignedSaturateLimit(TrueVal,
false))
2178 NewIntrinsicID = Intrinsic::ssub_sat;
2199 if (ExtOpcode != Instruction::ZExt && ExtOpcode != Instruction::SExt)
2205 Type *SmallType =
X->getType();
2207 auto *
Cmp = dyn_cast<CmpInst>(
Cond);
2209 (!Cmp ||
Cmp->getOperand(0)->getType() != SmallType))
2217 Value *TruncCVal = cast<Value>(TruncC);
2233 Value *CondVal =
SI.getCondition();
2235 auto *CondValTy = dyn_cast<FixedVectorType>(CondVal->
getType());
2239 unsigned NumElts = CondValTy->getNumElements();
2241 Mask.reserve(NumElts);
2242 for (
unsigned i = 0; i != NumElts; ++i) {
2252 Mask.push_back(i + NumElts);
2253 }
else if (isa<UndefValue>(Elt)) {
2273 auto *Ty = dyn_cast<VectorType>(Sel.
getType());
2305 if (TVal ==
A || TVal ==
B || FVal ==
A || FVal ==
B)
2322 if (TSrc ==
C && FSrc ==
D) {
2326 }
else if (TSrc ==
D && FSrc ==
C) {
2365 auto *Extract = dyn_cast<ExtractValueInst>(V);
2368 if (Extract->getIndices()[0] !=
I)
2370 return dyn_cast<AtomicCmpXchgInst>(Extract->getAggregateOperand());
2376 if (
auto *
Select = dyn_cast<SelectInst>(
SI.user_back()))
2377 if (
Select->getCondition() ==
SI.getCondition())
2378 if (
Select->getFalseValue() ==
SI.getTrueValue() ||
2379 Select->getTrueValue() ==
SI.getFalseValue())
2383 auto *CmpXchg = isExtractFromCmpXchg(
SI.getCondition(), 1);
2390 if (
auto *
X = isExtractFromCmpXchg(
SI.getTrueValue(), 0))
2391 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getFalseValue())
2392 return SI.getFalseValue();
2397 if (
auto *
X = isExtractFromCmpXchg(
SI.getFalseValue(), 0))
2398 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getTrueValue())
2399 return SI.getFalseValue();
2423 Value *SV0, *SV1, *SA0, *SA1;
2432 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2438 Or1->
getOpcode() == BinaryOperator::LShr &&
2439 "Illegal or(shift,shift) pair");
2454 bool IsFshl = (ShAmt == SA0);
2456 if ((IsFshl && TVal != SV0) || (!IsFshl && TVal != SV1))
2477 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
2498 assert(TC != FC &&
"Expected equal select arms to simplify");
2502 bool IsTrueIfSignSet;
2520 Value *MagArg = ConstantFP::get(SelType,
abs(*TC));
2527 if (!isa<VectorType>(Sel.
getType()))
2538 if (
auto *
I = dyn_cast<Instruction>(V))
2539 I->copyIRFlags(&Sel);
2550 return createSelReverse(
C,
X,
Y);
2554 return createSelReverse(
C,
X, FVal);
2559 return createSelReverse(
C, TVal,
Y);
2562 auto *VecTy = dyn_cast<FixedVectorType>(Sel.
getType());
2566 unsigned NumElts = VecTy->getNumElements();
2567 APInt PoisonElts(NumElts, 0);
2581 cast<ShuffleVectorInst>(TVal)->isSelect()) {
2595 cast<ShuffleVectorInst>(FVal)->isSelect()) {
2616 auto *IDomNode = DT[BB]->getIDom();
2622 Value *IfTrue, *IfFalse;
2638 if (TrueSucc == FalseSucc)
2659 if (
auto *
Insn = dyn_cast<Instruction>(Inputs[Pred]))
2678 if (
auto *
I = dyn_cast<Instruction>(V))
2679 CandidateBlocks.
insert(
I->getParent());
2682 if (
auto *PN = foldSelectToPhiImpl(Sel, BB, DT, Builder))
2695 Value *CondVal =
SI.getCondition();
2700 Value *
Op, *RemRes, *Remainder;
2702 bool TrueIfSigned =
false;
2716 return BinaryOperator::CreateAnd(
Op,
Add);
2728 return FoldToBitwiseAnd(Remainder);
2737 return FoldToBitwiseAnd(ConstantInt::get(RemRes->
getType(), 2));
2773 Value *InnerCondVal =
SI.getCondition();
2774 Value *InnerTrueVal =
SI.getTrueValue();
2775 Value *InnerFalseVal =
SI.getFalseValue();
2777 "The type of inner condition must match with the outer.");
2779 return *Implied ? InnerTrueVal : InnerFalseVal;
2786 assert(
Op->getType()->isIntOrIntVectorTy(1) &&
2787 "Op must be either i1 or vector of i1.");
2788 if (
SI.getCondition()->getType() !=
Op->getType())
2790 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(SI,
Op, IsAnd,
DL))
2801 Value *CondVal =
SI.getCondition();
2803 bool ChangedFMF =
false;
2804 for (
bool Swap : {
false,
true}) {
2834 FastMathFlags FMF = cast<FPMathOperator>(TrueVal)->getFastMathFlags();
2835 if (FMF.
noNaNs() && !
SI.hasNoNaNs()) {
2836 SI.setHasNoNaNs(
true);
2839 if (FMF.
noInfs() && !
SI.hasNoInfs()) {
2840 SI.setHasNoInfs(
true);
2854 if (!
SI.hasNoSignedZeros() || !
SI.hasNoNaNs())
2871 Instruction *NewFNeg = UnaryOperator::CreateFNeg(Fabs);
2880 for (
bool Swap : {
false,
true}) {
2896 if (Swap == TrueIfSigned && !CondVal->
hasOneUse() && !
TrueVal->hasOneUse())
2902 if (Swap != TrueIfSigned)
2907 return ChangedFMF ? &
SI :
nullptr;
2925foldRoundUpIntegerWithPow2Alignment(
SelectInst &SI,
2929 Value *XBiasedHighBits =
SI.getFalseValue();
2942 const APInt *LowBitMaskCst;
2947 const APInt *BiasCst, *HighBitMaskCst;
2948 if (!
match(XBiasedHighBits,
2951 !
match(XBiasedHighBits,
2956 if (!LowBitMaskCst->
isMask())
2959 APInt InvertedLowBitMaskCst = ~*LowBitMaskCst;
2960 if (InvertedLowBitMaskCst != *HighBitMaskCst)
2963 APInt AlignmentCst = *LowBitMaskCst + 1;
2965 if (*BiasCst != AlignmentCst && *BiasCst != *LowBitMaskCst)
2970 if (*BiasCst == *LowBitMaskCst &&
impliesPoison(XBiasedHighBits,
X))
2971 return XBiasedHighBits;
2976 Type *Ty =
X->getType();
2977 Value *XOffset = Builder.
CreateAdd(
X, ConstantInt::get(Ty, *LowBitMaskCst),
2978 X->getName() +
".biased");
2979 Value *
R = Builder.
CreateAnd(XOffset, ConstantInt::get(Ty, *HighBitMaskCst));
2985struct DecomposedSelect {
3002 DecomposedSelect OuterSel;
3009 std::swap(OuterSel.TrueVal, OuterSel.FalseVal);
3017 Value *InnerSelVal = IsAndVariant ? OuterSel.FalseVal : OuterSel.TrueVal;
3021 [](
Value *V) {
return V->hasOneUse(); }))
3025 DecomposedSelect InnerSel;
3026 if (!
match(InnerSelVal,
3033 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
3035 Value *AltCond =
nullptr;
3036 auto matchOuterCond = [OuterSel, IsAndVariant, &AltCond](
auto m_InnerCond) {
3041 return IsAndVariant ?
match(OuterSel.Cond,
3051 if (matchOuterCond(
m_Specific(InnerSel.Cond))) {
3056 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
3057 InnerSel.Cond = NotInnerCond;
3062 AltCond, IsAndVariant ? OuterSel.TrueVal : InnerSel.FalseVal,
3063 IsAndVariant ? InnerSel.TrueVal : OuterSel.FalseVal);
3066 IsAndVariant ? SelInner : InnerSel.TrueVal,
3067 !IsAndVariant ? SelInner : InnerSel.FalseVal);
3071 Value *CondVal =
SI.getCondition();
3074 Type *SelType =
SI.getType();
3093 return BinaryOperator::CreateOr(CondVal, FalseVal);
3103 if (
auto *LHS = dyn_cast<FCmpInst>(CondVal))
3104 if (
auto *RHS = dyn_cast<FCmpInst>(FalseVal))
3105 if (
Value *V = foldLogicOfFCmps(LHS, RHS,
false,
3113 bool CondLogicAnd = isa<SelectInst>(CondVal);
3114 bool FalseLogicAnd = isa<SelectInst>(FalseVal);
3115 auto AndFactorization = [&](
Value *Common,
Value *InnerCond,
3121 if (FalseLogicAnd || (CondLogicAnd && Common ==
A))
3124 return BinaryOperator::CreateAnd(Common, InnerSel);
3128 return AndFactorization(
A,
B,
D);
3130 return AndFactorization(
A,
B,
C);
3132 return AndFactorization(
B,
A,
D);
3134 return AndFactorization(
B,
A,
C, CondLogicAnd && FalseLogicAnd);
3141 return BinaryOperator::CreateAnd(CondVal, TrueVal);
3151 if (
auto *LHS = dyn_cast<FCmpInst>(CondVal))
3152 if (
auto *RHS = dyn_cast<FCmpInst>(TrueVal))
3153 if (
Value *V = foldLogicOfFCmps(LHS, RHS,
true,
3161 bool CondLogicOr = isa<SelectInst>(CondVal);
3162 bool TrueLogicOr = isa<SelectInst>(TrueVal);
3163 auto OrFactorization = [&](
Value *Common,
Value *InnerCond,
3169 if (TrueLogicOr || (CondLogicOr && Common ==
A))
3172 return BinaryOperator::CreateOr(Common, InnerSel);
3176 return OrFactorization(
A,
B,
D);
3178 return OrFactorization(
A,
B,
C);
3180 return OrFactorization(
B,
A,
D);
3182 return OrFactorization(
B,
A,
C, CondLogicOr && TrueLogicOr);
3225 return BinaryOperator::CreateXor(
A,
B);
3259 auto *FI =
new FreezeInst(*
Y, (*Y)->getName() +
".fr");
3265 if (
auto *ICmp0 = dyn_cast<ICmpInst>(CondVal))
3266 if (
auto *ICmp1 = dyn_cast<ICmpInst>(Op1))
3267 if (
auto *V = foldAndOrOfICmps(ICmp0, ICmp1, SI, IsAnd,
3278 if (Res && *Res ==
false)
3284 if (Res && *Res ==
false)
3293 if (Res && *Res ==
true)
3299 if (Res && *Res ==
true)
3312 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3313 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3314 bool MayNeedFreeze = SelCond && SelFVal &&
3315 match(SelFVal->getTrueValue(),
3328 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3329 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3330 bool MayNeedFreeze = SelCond && SelFVal &&
3331 match(SelCond->getTrueValue(),
3347 bool &ShouldDropNUW) {
3370 ShouldDropNUW =
false;
3376 auto MatchForward = [&](
Value *CommonAncestor) {
3377 const APInt *
C =
nullptr;
3378 if (CtlzOp == CommonAncestor)
3385 ShouldDropNUW =
true;
3396 const APInt *
C =
nullptr;
3397 Value *CommonAncestor;
3398 if (MatchForward(Cond0)) {
3402 if (!MatchForward(CommonAncestor))
3439 Type *SelType =
SI.getType();
3446 Value *Cond0, *Ctlz, *CtlzOp;
3462 !isSafeToRemoveBitCeilSelect(Pred, Cond0, Cond1, CtlzOp,
BitWidth,
3467 cast<Instruction>(CtlzOp)->setHasNoUnsignedWrap(
false);
3495 FastMathFlags FMF = cast<FPMathOperator>(TrueVal)->getFastMathFlags();
3506 Value *CondVal =
SI.getCondition();
3509 Type *SelType =
SI.getType();
3518 if (
Instruction *
I = canonicalizeScalarSelectOfVecs(SI, *
this))
3554 return new ZExtInst(CondVal, SelType);
3558 return new SExtInst(CondVal, SelType);
3563 return new ZExtInst(NotCond, SelType);
3569 return new SExtInst(NotCond, SelType);
3573 auto *SIFPOp = dyn_cast<FPMathOperator>(&SI);
3575 if (
auto *FCmp = dyn_cast<FCmpInst>(CondVal)) {
3577 Value *Cmp0 = FCmp->getOperand(0), *Cmp1 = FCmp->getOperand(1);
3579 if ((Cmp0 == TrueVal && Cmp1 == FalseVal) ||
3580 (Cmp0 == FalseVal && Cmp1 == TrueVal)) {
3592 FCmp->getName() +
".inv");
3612 Value *MatchCmp0 =
nullptr;
3613 Value *MatchCmp1 =
nullptr;
3625 if (Cmp0 == MatchCmp0 &&
3626 matchFMulByZeroIfResultEqZero(*
this, Cmp0, Cmp1, MatchCmp1, MatchCmp0,
3627 SI, SIFPOp->hasNoSignedZeros()))
3637 if (SIFPOp->hasNoNaNs() && SIFPOp->hasNoSignedZeros()) {
3650 if (
Instruction *Fabs = foldSelectWithFCmpToFabs(SI, *
this))
3654 if (
ICmpInst *ICI = dyn_cast<ICmpInst>(CondVal))
3668 auto *TI = dyn_cast<Instruction>(TrueVal);
3669 auto *FI = dyn_cast<Instruction>(FalseVal);
3670 if (TI && FI && TI->getOpcode() == FI->
getOpcode())
3689 if (isa<VectorType>(CondVal->
getType()) && !isa<VectorType>(
Idx->getType()))
3702 if (
auto *TrueGep = dyn_cast<GetElementPtrInst>(TrueVal))
3703 if (
auto *NewGep = SelectGepWithBase(TrueGep, FalseVal,
false))
3705 if (
auto *FalseGep = dyn_cast<GetElementPtrInst>(FalseVal))
3706 if (
auto *NewGep = SelectGepWithBase(FalseGep, TrueVal,
true))
3722 RHS2, SI, SPF, RHS))
3726 RHS2, SI, SPF, LHS))
3735 bool IsCastNeeded =
LHS->
getType() != SelType;
3736 Value *CmpLHS = cast<CmpInst>(CondVal)->getOperand(0);
3737 Value *CmpRHS = cast<CmpInst>(CondVal)->getOperand(1);
3740 ((CmpLHS != LHS && CmpLHS != RHS) ||
3741 (CmpRHS != LHS && CmpRHS != RHS)))) {
3750 cast<FPMathOperator>(
SI.getCondition())->getFastMathFlags();
3766 if (
auto *PN = dyn_cast<PHINode>(
SI.getCondition()))
3768 if (canSelectOperandBeMappingIntoPredBlock(TrueVal, SI) &&
3769 canSelectOperandBeMappingIntoPredBlock(FalseVal, SI))
3773 if (
SelectInst *TrueSI = dyn_cast<SelectInst>(TrueVal)) {
3774 if (TrueSI->getCondition()->getType() == CondVal->
getType()) {
3777 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(
3778 *TrueSI, CondVal,
true,
DL))
3785 if (TrueSI->getFalseValue() == FalseVal && TrueSI->hasOneUse()) {
3793 if (
SelectInst *FalseSI = dyn_cast<SelectInst>(FalseVal)) {
3794 if (FalseSI->getCondition()->getType() == CondVal->
getType()) {
3797 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(
3798 *FalseSI, CondVal,
false,
DL))
3802 if (FalseSI->getTrueValue() == TrueVal && FalseSI->hasOneUse()) {
3819 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(0))) {
3820 if (TrueBOSI->getCondition() == CondVal) {
3826 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(1))) {
3827 if (TrueBOSI->getCondition() == CondVal) {
3838 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(0))) {
3839 if (FalseBOSI->getCondition() == CondVal) {
3845 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(1))) {
3846 if (FalseBOSI->getCondition() == CondVal) {
3859 SI.swapProfMetadata();
3874 if (Known.One.isOne())
3876 if (Known.Zero.isOne())
3884 if (
Value *V = foldSelectCmpXchg(SI))
3902 if (
Value *V = foldRoundUpIntegerWithPow2Alignment(SI,
Builder))
3912 auto *MaskedInst = cast<IntrinsicInst>(TrueVal);
3913 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
3914 MaskedInst->setArgOperand(3, FalseVal );
3929 bool CanMergeSelectIntoLoad =
false;
3933 if (CanMergeSelectIntoLoad) {
3934 auto *MaskedInst = cast<IntrinsicInst>(FalseVal);
3935 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
3936 MaskedInst->setArgOperand(3, TrueVal );
3959 auto FoldSelectWithAndOrCond = [&](
bool IsAnd,
Value *
A,
3967 if (
ICmpInst *Cmp = dyn_cast<ICmpInst>(
B))
3968 if (
Value *V = canonicalizeSPF(*Cmp, TrueVal, FalseVal, *
this))
3970 IsAnd ? FalseVal : V);
3978 if (
Instruction *
I = FoldSelectWithAndOrCond(
true, LHS, RHS))
3980 if (
Instruction *
I = FoldSelectWithAndOrCond(
true, RHS, LHS))
3983 if (
Instruction *
I = FoldSelectWithAndOrCond(
false, LHS, RHS))
3985 if (
Instruction *
I = FoldSelectWithAndOrCond(
false, RHS, LHS))
3991 if (
Instruction *
I = FoldSelectWithAndOrCond(
true, LHS, RHS))
3994 if (
Instruction *
I = FoldSelectWithAndOrCond(
false, LHS, RHS))
SmallVector< AArch64_IMM::ImmInsnModel, 4 > Insn
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
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.
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 ugt(const APInt &RHS) const
Unsigned greater than comparison.
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...
static BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name, BasicBlock::iterator InsertBefore)
Construct a binary instruction, given the opcode and the two operands.
BinaryOps getOpcode() const
static BinaryOperator * CreateNot(Value *Op, const Twine &Name, BasicBlock::iterator InsertBefore)
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr, BasicBlock::iterator InsertBefore)
static CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name, BasicBlock::iterator InsertBefore)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
static CastInst * CreateBitOrPointerCast(Value *S, Type *Ty, const Twine &Name, BasicBlock::iterator InsertBefore)
Create a BitCast, a PtrToInt, or an IntToPTr cast instruction.
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
bool isInBounds() const
Determine whether the GEP has the inbounds flag.
Value * getPointerOperand()
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr, BasicBlock::iterator InsertBefore)
Type * getResultElementType() const
static GetElementPtrInst * CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr, BasicBlock::iterator InsertBefore)
Create an "inbounds" getelementptr.
uint64_t getType(const MachineInstr &MI) const
This instruction compares its operands according to the predicate given to the constructor.
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)
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.
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...
const BasicBlock * getParent() const
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.
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
A Module instance is used to store all the information related to an LLVM module.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
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, BasicBlock::iterator InsertBefore, 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 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 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, BasicBlock::iterator InsertBefore)
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.
LLVMContext & getContext() const
All values hold a context through their type.
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.
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.
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.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
match_combine_or< CastInst_match< OpTy, ZExtInst >, OpTy > m_ZExtOrSelf(const OpTy &Op)
bool match(Val *V, const Pattern &P)
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
constantexpr_match m_ConstantExpr()
Match a constant expression or a constant that contains a constant expression.
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)
CastOperator_match< OpTy, Instruction::Trunc > m_Trunc(const OpTy &Op)
Matches Trunc.
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.
CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
match_combine_or< CastOperator_match< OpTy, Instruction::Trunc >, OpTy > m_TruncOrSelf(const OpTy &Op)
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)
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 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 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...
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.
constexpr int PoisonMaskElem
@ Or
Bitwise or logical OR of integers.
@ Mul
Product of integers.
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
Return true if the instruction does not have any effects besides calculating the result and does not ...
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 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 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