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))
122 const APInt *SelTC, *SelFC;
129 if (SelType->
isVectorTy() != Cmp->getType()->isVectorTy())
134 bool CreateAnd =
false;
140 V = Cmp->getOperand(0);
163 if (!TC.
isZero() && !FC.isZero()) {
172 if (!Cmp->hasOneUse())
176 bool ExtraBitInTC = TC.
ugt(FC);
177 if (Pred == ICmpInst::ICMP_EQ) {
184 if (Pred == ICmpInst::ICMP_NE) {
201 unsigned ValZeros = ValC.
logBase2();
202 unsigned AndZeros = AndMask.
logBase2();
210 if (ValZeros > AndZeros) {
211 V =
Builder.CreateZExtOrTrunc(V, SelType);
212 V =
Builder.CreateShl(V, ValZeros - AndZeros);
213 }
else if (ValZeros < AndZeros) {
214 V =
Builder.CreateLShr(V, AndZeros - ValZeros);
215 V =
Builder.CreateZExtOrTrunc(V, SelType);
217 V =
Builder.CreateZExtOrTrunc(V, SelType);
222 bool ShouldNotVal = !TC.
isZero();
223 ShouldNotVal ^= Pred == ICmpInst::ICMP_NE;
225 V =
Builder.CreateXor(V, ValC);
241 switch (
I->getOpcode()) {
242 case Instruction::Add:
243 case Instruction::FAdd:
244 case Instruction::Mul:
245 case Instruction::FMul:
246 case Instruction::And:
247 case Instruction::Or:
248 case Instruction::Xor:
250 case Instruction::Sub:
251 case Instruction::FSub:
252 case Instruction::FDiv:
253 case Instruction::Shl:
254 case Instruction::LShr:
255 case Instruction::AShr:
285 if (
auto *CondVTy = dyn_cast<VectorType>(CondTy)) {
287 CondVTy->getElementCount() !=
288 cast<VectorType>(FIOpndTy)->getElementCount())
299 if (TI->
getOpcode() != Instruction::BitCast &&
312 SI.getName() +
".v", &
SI);
317 Value *OtherOpT, *OtherOpF;
320 bool Swapped =
false) ->
Value * {
321 assert(!(Commute && Swapped) &&
322 "Commute and Swapped can't set at the same time");
327 MatchIsOpZero =
true;
332 MatchIsOpZero =
false;
337 if (!Commute && !Swapped)
346 MatchIsOpZero =
true;
351 MatchIsOpZero =
false;
365 FMF |=
SI.getFastMathFlags();
368 if (
auto *NewSelI = dyn_cast<Instruction>(NewSel))
369 NewSelI->setFastMathFlags(FMF);
370 Instruction *NewFNeg = UnaryOperator::CreateFNeg(NewSel);
379 auto *
TII = dyn_cast<IntrinsicInst>(TI);
380 auto *FII = dyn_cast<IntrinsicInst>(FI);
381 if (
TII && FII &&
TII->getIntrinsicID() == FII->getIntrinsicID()) {
383 if (
Value *MatchOp = getCommonOp(TI, FI,
true)) {
397 bool Swapped = TPred != FPred;
401 SI.getName() +
".v", &
SI);
416 (!isa<BinaryOperator>(TI) && !isa<GetElementPtrInst>(TI)) ||
434 SI.getName() +
".v", &
SI);
435 Value *Op0 = MatchIsOpZero ? MatchOp : NewSI;
436 Value *Op1 = MatchIsOpZero ? NewSI : MatchOp;
437 if (
auto *BO = dyn_cast<BinaryOperator>(TI)) {
443 if (
auto *TGEP = dyn_cast<GetElementPtrInst>(TI)) {
444 auto *FGEP = cast<GetElementPtrInst>(FI);
445 Type *ElementType = TGEP->getResultElementType();
446 return TGEP->isInBounds() && FGEP->isInBounds()
469 auto *TVI = dyn_cast<BinaryOperator>(TrueVal);
470 if (!TVI || !TVI->hasOneUse() || isa<Constant>(FalseVal))
474 unsigned OpToFold = 0;
475 if ((SFO & 1) && FalseVal == TVI->getOperand(0))
477 else if ((SFO & 2) && FalseVal == TVI->getOperand(1))
487 if (isa<FPMathOperator>(&
SI))
488 FMF =
SI.getFastMathFlags();
490 TVI->getOpcode(), TVI->getType(),
true, FMF.
noSignedZeros());
491 Value *OOp = TVI->getOperand(2 - OpToFold);
496 if (!isa<Constant>(OOp) ||
497 (OOpIsAPInt &&
isSelect01(
C->getUniqueInteger(), *OOpC))) {
500 if (isa<FPMathOperator>(&
SI))
501 cast<Instruction>(NewSel)->setFastMathFlags(FMF);
511 if (
Instruction *R = TryFoldSelectIntoOp(
SI, TrueVal, FalseVal,
false))
514 if (
Instruction *R = TryFoldSelectIntoOp(
SI, FalseVal, TrueVal,
true))
531 if (!(Cmp->hasOneUse() && Cmp->getOperand(0)->hasOneUse() &&
564 Value *MaskB = HasShift ?
Builder.CreateShl(One, Z) : One;
568 return new ZExtInst(ICmpNeZero, SelType);
602 const auto *Ashr = cast<Instruction>(FalseVal);
604 bool IsExact = Ashr->isExact() && cast<Instruction>(TrueVal)->isExact();
629 if (!TrueVal->getType()->isIntOrIntVectorTy() ||
670 bool OrOnTrueVal =
false;
675 if (!OrOnFalseVal && !OrOnTrueVal)
678 Value *
Y = OrOnFalseVal ? TrueVal : FalseVal;
682 bool NeedXor = (!IsEqualZero && OrOnFalseVal) || (IsEqualZero && OrOnTrueVal);
683 bool NeedShift = C1Log != C2Log;
684 bool NeedZExtTrunc =
Y->getType()->getScalarSizeInBits() !=
688 Value *
Or = OrOnFalseVal ? FalseVal : TrueVal;
689 if ((NeedShift + NeedXor + NeedZExtTrunc) >
700 V =
Builder.CreateZExtOrTrunc(V,
Y->getType());
701 V =
Builder.CreateShl(V, C2Log - C1Log);
702 }
else if (C1Log > C2Log) {
703 V =
Builder.CreateLShr(V, C1Log - C2Log);
704 V =
Builder.CreateZExtOrTrunc(V,
Y->getType());
706 V =
Builder.CreateZExtOrTrunc(V,
Y->getType());
731 return BinaryOperator::CreateOr(
T, NewSel);
740 return BinaryOperator::CreateOr(
F, NewSel);
757 auto *CondVal =
SI.getCondition();
758 auto *TrueVal =
SI.getTrueValue();
759 auto *FalseVal =
SI.getFalseValue();
777 auto *TrueValC = dyn_cast<Constant>(TrueVal);
778 if (TrueValC ==
nullptr ||
780 !isa<Instruction>(FalseVal))
783 auto *ZeroC = cast<Constant>(cast<Instruction>(CondVal)->getOperand(1));
791 auto *FalseValI = cast<Instruction>(FalseVal);
794 IC.
replaceOperand(*FalseValI, FalseValI->getOperand(0) ==
Y ? 0 : 1, FrY);
802 const Value *TrueVal,
803 const Value *FalseVal,
823 return Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat,
A,
838 "Unexpected isUnsigned predicate!");
844 bool IsNegative =
false;
857 if (IsNegative && !TrueVal->hasOneUse() && !ICI->
hasOneUse())
862 Value *Result =
Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat,
A,
B);
864 Result =
Builder.CreateNeg(Result);
870 if (!Cmp->hasOneUse())
874 Value *Cmp0 = Cmp->getOperand(0);
875 Value *Cmp1 = Cmp->getOperand(1);
883 return Builder.CreateBinaryIntrinsic(
912 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat,
X,
Y);
922 return Builder.CreateBinaryIntrinsic(
932 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp1,
Y);
960 if (!
match(TrueVal, m_Intrinsic<Intrinsic::ctlz>()))
964 auto *II = cast<IntrinsicInst>(TrueVal);
1001 Value *Count =
nullptr;
1009 if (!
match(Count, m_Intrinsic<Intrinsic::cttz>(
m_Value(
X))) &&
1059 auto *SelEltTy = dyn_cast<IntegerType>(SelTy->
getScalarType());
1060 if (!SelEltTy || SelTy->
isVectorTy() !=
Cmp.getType()->isVectorTy())
1073 if ((CmpLHS == TrueVal && AdjustedRHS == FalseVal) ||
1074 (CmpLHS == FalseVal && AdjustedRHS == TrueVal)) {
1089 AdjustedRHS = SextRHS;
1091 SextRHS == TrueVal) {
1093 AdjustedRHS = SextRHS;
1094 }
else if (
Cmp.isUnsigned()) {
1102 AdjustedRHS = ZextRHS;
1104 ZextRHS == TrueVal) {
1106 AdjustedRHS = ZextRHS;
1118 CmpRHS = AdjustedRHS;
1120 Cmp.setPredicate(Pred);
1121 Cmp.setOperand(0, CmpLHS);
1122 Cmp.setOperand(1, CmpRHS);
1129 Cmp.moveBefore(&Sel);
1164 IntrinsicID = Intrinsic::umin;
1167 IntrinsicID = Intrinsic::umax;
1170 IntrinsicID = Intrinsic::smin;
1173 IntrinsicID = Intrinsic::smax;
1191 auto *
I = dyn_cast<Instruction>(V);
1195 bool Changed =
false;
1196 for (
Use &U :
I->operands()) {
1201 Changed |= replaceInInstruction(U, Old, New, IC,
Depth + 1);
1225 if (!
Cmp.isEquality())
1230 bool Swapped =
false;
1241 Value *CmpLHS =
Cmp.getOperand(0), *CmpRHS =
Cmp.getOperand(1);
1242 if (TrueVal != CmpLHS &&
1256 !
Cmp.getType()->isVectorTy())
1257 if (replaceInInstruction(TrueVal, CmpLHS, CmpRHS, *
this))
1260 if (TrueVal != CmpRHS &&
1266 auto *FalseInst = dyn_cast<Instruction>(FalseVal);
1273 bool WasNUW =
false, WasNSW =
false, WasExact =
false, WasInBounds =
false;
1274 if (
auto *OBO = dyn_cast<OverflowingBinaryOperator>(FalseVal)) {
1275 WasNUW = OBO->hasNoUnsignedWrap();
1276 WasNSW = OBO->hasNoSignedWrap();
1277 FalseInst->setHasNoUnsignedWrap(
false);
1278 FalseInst->setHasNoSignedWrap(
false);
1280 if (
auto *PEO = dyn_cast<PossiblyExactOperator>(FalseVal)) {
1281 WasExact = PEO->isExact();
1282 FalseInst->setIsExact(
false);
1284 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(FalseVal)) {
1285 WasInBounds =
GEP->isInBounds();
1286 GEP->setIsInBounds(
false);
1294 false) == TrueVal ||
1296 false) == TrueVal) {
1302 FalseInst->setHasNoUnsignedWrap();
1304 FalseInst->setHasNoSignedWrap();
1306 FalseInst->setIsExact();
1308 cast<GetElementPtrInst>(FalseInst)->setIsInBounds();
1343 if (!isa<SelectInst>(Sel1)) {
1384 if (Cmp00->
getType() !=
X->getType() &&
X->hasOneUse())
1392 else if (!
match(Cmp00,
1400 Value *ReplacementLow, *ReplacementHigh;
1437 std::swap(ReplacementLow, ReplacementHigh);
1443 "Unexpected predicate type.");
1451 "Unexpected predicate type.");
1453 std::swap(ThresholdLowIncl, ThresholdHighExcl);
1469 if (
X->getType() != Sel0.
getType()) {
1479 Value *ShouldReplaceLow =
Builder.CreateICmpSLT(
X, ThresholdLowIncl);
1480 Value *ShouldReplaceHigh =
Builder.CreateICmpSGE(
X, ThresholdHighExcl);
1481 Value *MaybeReplacedLow =
1482 Builder.CreateSelect(ShouldReplaceLow, ReplacementLow,
X);
1487 ShouldReplaceHigh, ReplacementHigh, MaybeReplacedLow);
1531 Value *SelVal0, *SelVal1;
1540 auto MatchesSelectValue = [SelVal0, SelVal1](
Constant *
C) {
1541 return C->isElementWiseEqual(SelVal0) ||
C->isElementWiseEqual(SelVal1);
1545 if (MatchesSelectValue(C0))
1549 auto FlippedStrictness =
1551 if (!FlippedStrictness)
1555 if (!MatchesSelectValue(FlippedStrictness->second))
1564 Cmp.getName() +
".inv");
1575 if (!
Cmp->hasOneUse())
1613 const APInt *BinOpC;
1632 if (
Instruction *NewSPF = canonicalizeSPF(SI, *ICI, *
this))
1635 if (
Value *V = foldSelectInstWithICmpConst(SI, ICI))
1638 if (
Value *V = canonicalizeClampLike(SI, *ICI,
Builder))
1642 tryToReuseConstantFromSelectInComparison(SI, *ICI, *
this))
1645 bool Changed = adjustMinMax(SI, *ICI);
1656 if (CmpRHS != CmpLHS && isa<Constant>(CmpRHS)) {
1659 SI.setOperand(1, CmpRHS);
1663 SI.setOperand(2, CmpRHS);
1680 SI.swapProfMetadata();
1693 bool IsBitTest =
false;
1701 Y = &MinSignedValue;
1703 TrueWhenUnset =
false;
1706 Y = &MinSignedValue;
1708 TrueWhenUnset =
true;
1713 if (TrueWhenUnset && TrueVal ==
X &&
1717 else if (!TrueWhenUnset && FalseVal ==
X &&
1721 else if (TrueWhenUnset && FalseVal ==
X &&
1725 else if (!TrueWhenUnset && TrueVal ==
X &&
1750 if (
Value *V = foldSelectCttzCtlz(ICI, TrueVal, FalseVal,
Builder))
1759 return Changed ? &
SI :
nullptr;
1771static bool canSelectOperandBeMappingIntoPredBlock(
const Value *V,
1776 if (!
I)
return true;
1780 const PHINode *CondPHI = cast<PHINode>(
SI.getCondition());
1782 if (
const PHINode *VP = dyn_cast<PHINode>(
I))
1783 if (VP->getParent() == CondPHI->
getParent())
1807 if (
C ==
A ||
C ==
B) {
1822 Value *CondVal =
SI.getCondition();
1825 auto *TI = dyn_cast<Instruction>(TrueVal);
1826 auto *FI = dyn_cast<Instruction>(FalseVal);
1827 if (!TI || !FI || !TI->hasOneUse() || !FI->hasOneUse())
1831 if ((TI->getOpcode() == Instruction::Sub &&
1832 FI->getOpcode() == Instruction::Add) ||
1833 (TI->getOpcode() == Instruction::FSub &&
1834 FI->getOpcode() == Instruction::FAdd)) {
1837 }
else if ((FI->getOpcode() == Instruction::Sub &&
1838 TI->getOpcode() == Instruction::Add) ||
1839 (FI->getOpcode() == Instruction::FSub &&
1840 TI->getOpcode() == Instruction::FAdd)) {
1846 Value *OtherAddOp =
nullptr;
1847 if (SubOp->getOperand(0) == AddOp->
getOperand(0)) {
1849 }
else if (SubOp->getOperand(0) == AddOp->
getOperand(1)) {
1857 if (
SI.getType()->isFPOrFPVectorTy()) {
1858 NegVal =
Builder.CreateFNeg(SubOp->getOperand(1));
1859 if (
Instruction *NegInst = dyn_cast<Instruction>(NegVal)) {
1861 Flags &= SubOp->getFastMathFlags();
1862 NegInst->setFastMathFlags(Flags);
1865 NegVal =
Builder.CreateNeg(SubOp->getOperand(1));
1868 Value *NewTrueOp = OtherAddOp;
1869 Value *NewFalseOp = NegVal;
1872 Value *NewSel =
Builder.CreateSelect(CondVal, NewTrueOp, NewFalseOp,
1873 SI.getName() +
".p", &SI);
1875 if (
SI.getType()->isFPOrFPVectorTy()) {
1877 BinaryOperator::CreateFAdd(SubOp->getOperand(0), NewSel);
1880 Flags &= SubOp->getFastMathFlags();
1884 return BinaryOperator::CreateAdd(SubOp->getOperand(0), NewSel);
1897 Value *CondVal =
SI.getCondition();
1909 auto IsSignedSaturateLimit = [&](
Value *Limit,
bool IsAdd) {
1919 auto IsZeroOrOne = [](
const APInt &
C) {
return C.isZero() ||
C.isOne(); };
1927 if (Op !=
X && Op !=
Y)
1936 IsMinMax(TrueVal, FalseVal))
1943 IsMinMax(FalseVal, TrueVal))
1949 IsMinMax(TrueVal, FalseVal))
1954 IsMinMax(FalseVal, TrueVal))
1959 IsMinMax(FalseVal, TrueVal))
1964 IsMinMax(TrueVal, FalseVal))
1975 NewIntrinsicID = Intrinsic::uadd_sat;
1976 else if (II->
getIntrinsicID() == Intrinsic::usub_with_overflow &&
1979 NewIntrinsicID = Intrinsic::usub_sat;
1980 else if (II->
getIntrinsicID() == Intrinsic::sadd_with_overflow &&
1981 IsSignedSaturateLimit(TrueVal,
true))
1990 NewIntrinsicID = Intrinsic::sadd_sat;
1991 else if (II->
getIntrinsicID() == Intrinsic::ssub_with_overflow &&
1992 IsSignedSaturateLimit(TrueVal,
false))
2001 NewIntrinsicID = Intrinsic::ssub_sat;
2022 if (ExtOpcode != Instruction::ZExt && ExtOpcode != Instruction::SExt)
2028 Type *SmallType =
X->getType();
2030 auto *
Cmp = dyn_cast<CmpInst>(
Cond);
2032 (!Cmp ||
Cmp->getOperand(0)->getType() != SmallType))
2041 Value *TruncCVal = cast<Value>(TruncC);
2074 Value *CondVal =
SI.getCondition();
2076 auto *CondValTy = dyn_cast<FixedVectorType>(CondVal->
getType());
2080 unsigned NumElts = CondValTy->getNumElements();
2082 Mask.reserve(NumElts);
2083 for (
unsigned i = 0; i != NumElts; ++i) {
2093 Mask.push_back(i + NumElts);
2094 }
else if (isa<UndefValue>(Elt)) {
2114 auto *Ty = dyn_cast<VectorType>(Sel.
getType());
2146 if (TVal ==
A || TVal ==
B || FVal ==
A || FVal ==
B)
2163 if (TSrc ==
C && FSrc ==
D) {
2167 }
else if (TSrc ==
D && FSrc ==
C) {
2206 auto *Extract = dyn_cast<ExtractValueInst>(V);
2209 if (Extract->getIndices()[0] !=
I)
2211 return dyn_cast<AtomicCmpXchgInst>(Extract->getAggregateOperand());
2217 if (
auto *
Select = dyn_cast<SelectInst>(
SI.user_back()))
2218 if (
Select->getCondition() ==
SI.getCondition())
2219 if (
Select->getFalseValue() ==
SI.getTrueValue() ||
2220 Select->getTrueValue() ==
SI.getFalseValue())
2224 auto *CmpXchg = isExtractFromCmpXchg(
SI.getCondition(), 1);
2231 if (
auto *
X = isExtractFromCmpXchg(
SI.getTrueValue(), 0))
2232 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getFalseValue())
2233 return SI.getFalseValue();
2238 if (
auto *
X = isExtractFromCmpXchg(
SI.getFalseValue(), 0))
2239 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getTrueValue())
2240 return SI.getFalseValue();
2264 Value *SV0, *SV1, *SA0, *SA1;
2273 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2279 Or1->
getOpcode() == BinaryOperator::LShr &&
2280 "Illegal or(shift,shift) pair");
2295 bool IsFshl = (ShAmt == SA0);
2297 if ((IsFshl && TVal != SV0) || (!IsFshl && TVal != SV1))
2311 SV1 =
Builder.CreateFreeze(SV1);
2313 SV0 =
Builder.CreateFreeze(SV0);
2318 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
2339 assert(TC != FC &&
"Expected equal select arms to simplify");
2343 bool IsTrueIfSignSet;
2347 X->getType() != SelType)
2368 if (!isa<VectorType>(Sel.
getType()))
2379 if (
auto *
I = dyn_cast<Instruction>(V))
2380 I->copyIRFlags(&Sel);
2383 M, Intrinsic::experimental_vector_reverse, V->
getType());
2391 return createSelReverse(
C,
X,
Y);
2395 return createSelReverse(
C,
X, FVal);
2400 return createSelReverse(
C, TVal,
Y);
2403 auto *VecTy = dyn_cast<FixedVectorType>(Sel.
getType());
2407 unsigned NumElts = VecTy->getNumElements();
2408 APInt UndefElts(NumElts, 0);
2422 cast<ShuffleVectorInst>(TVal)->isSelect()) {
2436 cast<ShuffleVectorInst>(FVal)->isSelect()) {
2457 auto *IDomNode = DT[BB]->getIDom();
2463 Value *IfTrue, *IfFalse;
2479 if (TrueSucc == FalseSucc)
2495 else if (DT.
dominates(FalseEdge, Incoming))
2500 if (
auto *
Insn = dyn_cast<Instruction>(Inputs[Pred]))
2508 PN->addIncoming(Inputs[Pred], Pred);
2519 if (
auto *
I = dyn_cast<Instruction>(V))
2520 CandidateBlocks.
insert(
I->getParent());
2523 if (
auto *PN = foldSelectToPhiImpl(Sel, BB, DT, Builder))
2557 Value *CondVal =
SI.getCondition();
2561 assert(
Op->getType()->isIntOrIntVectorTy(1) &&
2562 "Op must be either i1 or vector of i1.");
2600 Value *CondVal =
SI.getCondition();
2602 bool ChangedFMF =
false;
2603 for (
bool Swap : {
false,
true}) {
2633 FastMathFlags FMF = cast<FPMathOperator>(TrueVal)->getFastMathFlags();
2634 if (FMF.
noNaNs() && !
SI.hasNoNaNs()) {
2635 SI.setHasNoNaNs(
true);
2638 if (FMF.
noInfs() && !
SI.hasNoInfs()) {
2639 SI.setHasNoInfs(
true);
2653 if (!
SI.hasNoSignedZeros() || !
SI.hasNoNaNs())
2670 Instruction *NewFNeg = UnaryOperator::CreateFNeg(Fabs);
2676 return ChangedFMF ? &
SI :
nullptr;
2694foldRoundUpIntegerWithPow2Alignment(
SelectInst &SI,
2698 Value *XBiasedHighBits =
SI.getFalseValue();
2711 const APInt *LowBitMaskCst;
2716 const APInt *BiasCst, *HighBitMaskCst;
2717 if (!
match(XBiasedHighBits,
2720 !
match(XBiasedHighBits,
2725 if (!LowBitMaskCst->
isMask())
2728 APInt InvertedLowBitMaskCst = ~*LowBitMaskCst;
2729 if (InvertedLowBitMaskCst != *HighBitMaskCst)
2732 APInt AlignmentCst = *LowBitMaskCst + 1;
2734 if (*BiasCst != AlignmentCst && *BiasCst != *LowBitMaskCst)
2738 if (*BiasCst == *LowBitMaskCst)
2739 return XBiasedHighBits;
2744 Type *Ty =
X->getType();
2746 X->getName() +
".biased");
2753struct DecomposedSelect {
2770 DecomposedSelect OuterSel;
2777 std::swap(OuterSel.TrueVal, OuterSel.FalseVal);
2785 Value *InnerSelVal = IsAndVariant ? OuterSel.FalseVal : OuterSel.TrueVal;
2793 DecomposedSelect InnerSel;
2794 if (!
match(InnerSelVal,
2801 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
2803 Value *AltCond =
nullptr;
2804 auto matchOuterCond = [OuterSel, &AltCond](
auto m_InnerCond) {
2812 if (matchOuterCond(
m_Specific(InnerSel.Cond))) {
2817 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
2818 InnerSel.Cond = NotInnerCond;
2823 AltCond, IsAndVariant ? OuterSel.TrueVal : InnerSel.FalseVal,
2824 IsAndVariant ? InnerSel.TrueVal : OuterSel.FalseVal);
2827 IsAndVariant ? SelInner : InnerSel.TrueVal,
2828 !IsAndVariant ? SelInner : InnerSel.FalseVal);
2832 Value *CondVal =
SI.getCondition();
2835 Type *SelType =
SI.getType();
2854 return BinaryOperator::CreateOr(CondVal, FalseVal);
2857 if (
auto *LHS = dyn_cast<FCmpInst>(CondVal))
2858 if (
auto *RHS = dyn_cast<FCmpInst>(FalseVal))
2859 if (
Value *V = foldLogicOfFCmps(LHS, RHS,
false,
2867 bool CondLogicAnd = isa<SelectInst>(CondVal);
2868 bool FalseLogicAnd = isa<SelectInst>(FalseVal);
2869 auto AndFactorization = [&](
Value *Common,
Value *InnerCond,
2875 if (FalseLogicAnd || (CondLogicAnd && Common ==
A))
2878 return BinaryOperator::CreateAnd(Common, InnerSel);
2882 return AndFactorization(
A,
B,
D);
2884 return AndFactorization(
A,
B,
C);
2886 return AndFactorization(
B,
A,
D);
2888 return AndFactorization(
B,
A,
C, CondLogicAnd && FalseLogicAnd);
2895 return BinaryOperator::CreateAnd(CondVal, TrueVal);
2898 if (
auto *LHS = dyn_cast<FCmpInst>(CondVal))
2899 if (
auto *RHS = dyn_cast<FCmpInst>(TrueVal))
2900 if (
Value *V = foldLogicOfFCmps(LHS, RHS,
true,
2908 bool CondLogicOr = isa<SelectInst>(CondVal);
2909 bool TrueLogicOr = isa<SelectInst>(TrueVal);
2910 auto OrFactorization = [&](
Value *Common,
Value *InnerCond,
2916 if (TrueLogicOr || (CondLogicOr && Common ==
A))
2919 return BinaryOperator::CreateOr(Common, InnerSel);
2923 return OrFactorization(
A,
B,
D);
2925 return OrFactorization(
A,
B,
C);
2927 return OrFactorization(
B,
A,
D);
2929 return OrFactorization(
B,
A,
C, CondLogicOr && TrueLogicOr);
2972 return BinaryOperator::CreateXor(
A,
B);
2992 auto *FI =
new FreezeInst(*
Y, (*Y)->getName() +
".fr");
2998 if (
auto *Op1SI = dyn_cast<SelectInst>(Op1))
2999 if (
auto *
I = foldAndOrOfSelectUsingImpliedCond(CondVal, *Op1SI,
3003 if (
auto *ICmp0 = dyn_cast<ICmpInst>(CondVal))
3004 if (
auto *ICmp1 = dyn_cast<ICmpInst>(Op1))
3005 if (
auto *V = foldAndOrOfICmps(ICmp0, ICmp1, SI, IsAnd,
3016 if (Res && *Res ==
false)
3022 if (Res && *Res ==
false)
3031 if (Res && *Res ==
true)
3037 if (Res && *Res ==
true)
3050 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3051 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3052 bool MayNeedFreeze = SelCond && SelFVal &&
3053 match(SelFVal->getTrueValue(),
3066 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3067 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3068 bool MayNeedFreeze = SelCond && SelFVal &&
3069 match(SelCond->getTrueValue(),
3081 Value *CondVal =
SI.getCondition();
3084 Type *SelType =
SI.getType();
3093 if (
Instruction *
I = canonicalizeScalarSelectOfVecs(SI, *
this))
3151 return new ZExtInst(CondVal, SelType);
3155 return new SExtInst(CondVal, SelType);
3160 return new ZExtInst(NotCond, SelType);
3166 return new SExtInst(NotCond, SelType);
3170 if (
auto *FCmp = dyn_cast<FCmpInst>(CondVal)) {
3173 if ((Cmp0 == TrueVal && Cmp1 == FalseVal) ||
3174 (Cmp0 == FalseVal && Cmp1 == TrueVal)) {
3186 FCmp->getName() +
".inv");
3193 if (isa<FPMathOperator>(SI)) {
3198 if (
SI.hasNoNaNs() &&
SI.hasNoSignedZeros()) {
3211 if (
Instruction *Fabs = foldSelectWithFCmpToFabs(SI, *
this))
3215 if (
ICmpInst *ICI = dyn_cast<ICmpInst>(CondVal))
3229 auto *TI = dyn_cast<Instruction>(TrueVal);
3230 auto *FI = dyn_cast<Instruction>(FalseVal);
3231 if (TI && FI && TI->getOpcode() == FI->
getOpcode())
3247 if (isa<VectorType>(CondVal->
getType()) && !isa<VectorType>(
Idx->getType()))
3258 if (
auto *TrueGep = dyn_cast<GetElementPtrInst>(TrueVal))
3259 if (
auto *NewGep = SelectGepWithBase(TrueGep, FalseVal,
false))
3261 if (
auto *FalseGep = dyn_cast<GetElementPtrInst>(FalseVal))
3262 if (
auto *NewGep = SelectGepWithBase(FalseGep, TrueVal,
true))
3278 RHS2, SI, SPF, RHS))
3282 RHS2, SI, SPF, LHS))
3291 bool IsCastNeeded =
LHS->
getType() != SelType;
3292 Value *CmpLHS = cast<CmpInst>(CondVal)->getOperand(0);
3293 Value *CmpRHS = cast<CmpInst>(CondVal)->getOperand(1);
3296 ((CmpLHS != LHS && CmpLHS != RHS) ||
3297 (CmpRHS != LHS && CmpRHS != RHS)))) {
3306 cast<FPMathOperator>(
SI.getCondition())->getFastMathFlags();
3322 if (
auto *PN = dyn_cast<PHINode>(
SI.getCondition()))
3324 if (canSelectOperandBeMappingIntoPredBlock(TrueVal, SI) &&
3325 canSelectOperandBeMappingIntoPredBlock(FalseVal, SI))
3329 if (
SelectInst *TrueSI = dyn_cast<SelectInst>(TrueVal)) {
3330 if (TrueSI->getCondition()->getType() == CondVal->
getType()) {
3332 if (TrueSI->getCondition() == CondVal) {
3333 if (
SI.getTrueValue() == TrueSI->getTrueValue())
3341 if (TrueSI->getFalseValue() == FalseVal && TrueSI->hasOneUse()) {
3349 if (
SelectInst *FalseSI = dyn_cast<SelectInst>(FalseVal)) {
3350 if (FalseSI->getCondition()->getType() == CondVal->
getType()) {
3352 if (FalseSI->getCondition() == CondVal) {
3353 if (
SI.getFalseValue() == FalseSI->getFalseValue())
3358 if (FalseSI->getTrueValue() == TrueVal && FalseSI->hasOneUse()) {
3372 case Instruction::SRem:
3373 case Instruction::URem:
3374 case Instruction::SDiv:
3375 case Instruction::UDiv:
3385 canMergeSelectThroughBinop(TrueBO)) {
3386 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(0))) {
3387 if (TrueBOSI->getCondition() == CondVal) {
3393 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(1))) {
3394 if (TrueBOSI->getCondition() == CondVal) {
3405 canMergeSelectThroughBinop(FalseBO)) {
3406 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(0))) {
3407 if (FalseBOSI->getCondition() == CondVal) {
3413 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(1))) {
3414 if (FalseBOSI->getCondition() == CondVal) {
3427 SI.swapProfMetadata();
3442 if (Known.One.isOne())
3444 if (Known.Zero.isOne())
3452 if (
Value *V = foldSelectCmpXchg(SI))
3470 if (
Value *V = foldRoundUpIntegerWithPow2Alignment(SI,
Builder))
3480 auto *MaskedInst = cast<IntrinsicInst>(TrueVal);
3481 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
3482 MaskedInst->setArgOperand(3, FalseVal );
3497 bool CanMergeSelectIntoLoad =
false;
3501 if (CanMergeSelectIntoLoad) {
3502 auto *MaskedInst = cast<IntrinsicInst>(FalseVal);
3503 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
3504 MaskedInst->setArgOperand(3, TrueVal );
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...
SmallVector< MachineOperand, 4 > Cond
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 * foldSelectICmpAndOr(const ICmpInst *IC, Value *TrueVal, Value *FalseVal, InstCombiner::BuilderTy &Builder)
We want to turn: (select (icmp eq (and X, C1), 0), Y, (or Y, C2)) into: (or (shl (and X,...
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 * 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")
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.
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.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
unsigned logBase2() const
bool isMask(unsigned numBits) const
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.
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=Twine(), Instruction *InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
static BinaryOperator * CreateNeg(Value *Op, const Twine &Name="", Instruction *InsertBefore=nullptr)
Helper functions to construct and inspect unary operations (NEG and NOT) via binary operators SUB and...
BinaryOps getOpcode() const
static BinaryOperator * CreateNot(Value *Op, const Twine &Name="", Instruction *InsertBefore=nullptr)
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
static CastInst * CreateBitOrPointerCast(Value *S, Type *Ty, const Twine &Name="", Instruction *InsertBefore=nullptr)
Create a BitCast, a PtrToInt, or an IntToPTr cast instruction.
static CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", Instruction *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.
@ 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
@ 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
@ 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 * getCast(unsigned ops, Constant *C, Type *Ty, bool OnlyIfReduced=false)
Convenience function for getting a Cast operation.
static Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getZExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getICmp(unsigned short pred, Constant *LHS, Constant *RHS, bool OnlyIfReduced=false)
get* - Return some common constants without having to specify the full Instruction::OPCODE identifier...
static Constant * getSExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)
Return the identity constant for a binary opcode.
static Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getNeg(Constant *C, bool HasNUW=false, bool HasNSW=false)
static Constant * get(Type *Ty, double V)
This returns a ConstantFP, or a vector containing a splat of a ConstantFP, for the specified value in...
static ConstantInt * getTrue(LLVMContext &Context)
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
static ConstantInt * getFalse(LLVMContext &Context)
This class represents a range of values.
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 binaryOp(Instruction::BinaryOps BinOp, const ConstantRange &Other) const
Return a new range representing the possible values resulting from an application of the specified bi...
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.
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.
Convenience struct for specifying and reasoning about fast-math flags.
bool noSignedZeros() const
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
static GetElementPtrInst * CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Create an "inbounds" getelementptr.
Value * getPointerOperand()
Type * getResultElementType() const
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
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.
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 * CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")
Return a vector value that contains.
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Value * CreateFreeze(Value *V, const Twine &Name="")
void setFastMathFlags(FastMathFlags NewFMF)
Set the fast-math flags to be used with generated fp-math operators.
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateIsNeg(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg < 0.
CallInst * 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 * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateLogicalAnd(Value *Cond1, Value *Cond2, 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 * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateLogicalOr(Value *Cond1, Value *Cond2, const Twine &Name="")
Instruction * foldOpIntoPhi(Instruction &I, PHINode *PN)
Given a binary operator, cast instruction, or select which has a PHI node as operand #0,...
Value * SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, APInt &UndefElts, unsigned Depth=0, bool AllowMultipleUsers=false) override
The specified value produces a vector with any number of elements.
Instruction * foldVectorSelect(SelectInst &Sel)
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.
Instruction * foldSelectInstWithICmp(SelectInst &SI, ICmpInst *ICI)
bool sinkNotIntoOtherHandOfLogicalOp(Instruction &I)
Instruction * foldSelectIntoOp(SelectInst &SI, Value *, Value *)
Try to fold the select into one of the operands to allow further optimization.
Instruction * visitSelectInst(SelectInst &SI)
Instruction * foldSelectOfBools(SelectInst &SI)
Instruction * foldSelectExtConst(SelectInst &Sel)
The core instruction combiner logic.
static bool isCanonicalPredicate(CmpInst::Predicate Pred)
Predicate canonicalization reduces the number of patterns that need to be matched by other transforms...
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 * InsertNewInstBefore(Instruction *New, Instruction &Old)
Inserts an instruction New before instruction Old.
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
static 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.
void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth, const Instruction *CxtI) const
static Constant * AddOne(Constant *C)
Add one to a Constant.
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.
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
const Value * getTrueValue() const
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", Instruction *InsertBefore=nullptr, Instruction *MDFrom=nullptr)
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.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
A Use represents the edge between a Value definition and its users.
void setOperand(unsigned i, Value *Val)
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.
#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)
specific_intval< false > m_SpecificInt(APInt V)
Match a specific integer value or vector with all elements equal to the value.
match_combine_or< CastClass_match< OpTy, Instruction::ZExt >, OpTy > m_ZExtOrSelf(const OpTy &Op)
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.
apfloat_match m_APFloatAllowUndef(const APFloat *&Res)
Match APFloat while allowing undefs in splat vector constants.
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
apint_match m_APIntAllowUndef(const APInt *&Res)
Match APInt while allowing undefs in splat vector constants.
CastClass_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
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.
CastClass_match< OpTy, Instruction::SExt > m_SExt(const OpTy &Op)
Matches SExt.
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)
CastClass_match< OpTy, Instruction::ZExt > m_ZExt(const OpTy &Op)
Matches ZExt.
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)
bind_ty< WithOverflowInst > m_WithOverflowInst(WithOverflowInst *&I)
Match a with overflow intrinsic, capturing it if we match.
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.
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.
CastClass_match< OpTy, Instruction::Trunc > m_Trunc(const OpTy &Op)
Matches Trunc.
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.
match_combine_or< CastClass_match< OpTy, Instruction::Trunc >, OpTy > m_TruncOrSelf(const OpTy &Op)
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.
match_combine_or< CastClass_match< OpTy, Instruction::ZExt >, CastClass_match< OpTy, Instruction::SExt > > m_ZExtOrSExt(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.
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.
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.
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.
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.
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
APFloat abs(APFloat X)
Returns the absolute value of the argument.
CmpInst::Predicate getMinMaxPred(SelectPatternFlavor SPF, bool Ordered=false)
Return the canonical comparison predicate for the specified minimum/maximum flavor.
constexpr int UndefMaskElem
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.
Value * simplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an And, fold the result or return null.
@ Or
Bitwise or logical OR of integers.
@ Mul
Product of integers.
@ And
Bitwise or logical AND of integers.
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
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
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 isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
bool CannotBeNegativeZero(const Value *V, const TargetLibraryInfo *TLI, unsigned Depth=0)
Return true if we can prove that the specified FP value is never equal to -0.0.
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 * simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp, const SimplifyQuery &Q, bool AllowRefinement)
See if V simplifies when its operand Op is replaced with RepOp.
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.
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(Instruction *I) const