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)) ||
438 auto *BO = dyn_cast<BinaryOperator>(TI);
442 if (BO->getOpcode() == Instruction::SDiv ||
443 BO->getOpcode() == Instruction::SRem || MatchIsOpZero)
449 SI.getName() +
".v", &
SI);
450 Value *Op0 = MatchIsOpZero ? MatchOp : NewSI;
451 Value *Op1 = MatchIsOpZero ? NewSI : MatchOp;
452 if (
auto *BO = dyn_cast<BinaryOperator>(TI)) {
458 if (
auto *TGEP = dyn_cast<GetElementPtrInst>(TI)) {
459 auto *FGEP = cast<GetElementPtrInst>(FI);
460 Type *ElementType = TGEP->getResultElementType();
461 return TGEP->isInBounds() && FGEP->isInBounds()
484 auto *TVI = dyn_cast<BinaryOperator>(TrueVal);
485 if (!TVI || !TVI->hasOneUse() || isa<Constant>(FalseVal))
489 unsigned OpToFold = 0;
490 if ((SFO & 1) && FalseVal == TVI->getOperand(0))
492 else if ((SFO & 2) && FalseVal == TVI->getOperand(1))
502 if (isa<FPMathOperator>(&
SI))
503 FMF =
SI.getFastMathFlags();
505 TVI->getOpcode(), TVI->getType(),
true, FMF.
noSignedZeros());
506 Value *OOp = TVI->getOperand(2 - OpToFold);
511 if (!isa<Constant>(OOp) ||
512 (OOpIsAPInt &&
isSelect01(
C->getUniqueInteger(), *OOpC))) {
515 if (isa<FPMathOperator>(&
SI))
516 cast<Instruction>(NewSel)->setFastMathFlags(FMF);
526 if (
Instruction *R = TryFoldSelectIntoOp(
SI, TrueVal, FalseVal,
false))
529 if (
Instruction *R = TryFoldSelectIntoOp(
SI, FalseVal, TrueVal,
true))
546 if (!(Cmp->hasOneUse() && Cmp->getOperand(0)->hasOneUse() &&
579 Value *MaskB = HasShift ?
Builder.CreateShl(One, Z) : One;
583 return new ZExtInst(ICmpNeZero, SelType);
617 const auto *Ashr = cast<Instruction>(FalseVal);
619 bool IsExact = Ashr->isExact() && cast<Instruction>(TrueVal)->isExact();
644 if (!TrueVal->getType()->isIntOrIntVectorTy() ||
685 bool OrOnTrueVal =
false;
690 if (!OrOnFalseVal && !OrOnTrueVal)
693 Value *
Y = OrOnFalseVal ? TrueVal : FalseVal;
697 bool NeedXor = (!IsEqualZero && OrOnFalseVal) || (IsEqualZero && OrOnTrueVal);
698 bool NeedShift = C1Log != C2Log;
699 bool NeedZExtTrunc =
Y->getType()->getScalarSizeInBits() !=
700 V->getType()->getScalarSizeInBits();
703 Value *
Or = OrOnFalseVal ? FalseVal : TrueVal;
704 if ((NeedShift + NeedXor + NeedZExtTrunc) >
715 V =
Builder.CreateZExtOrTrunc(V,
Y->getType());
716 V =
Builder.CreateShl(V, C2Log - C1Log);
717 }
else if (C1Log > C2Log) {
718 V =
Builder.CreateLShr(V, C1Log - C2Log);
719 V =
Builder.CreateZExtOrTrunc(V,
Y->getType());
721 V =
Builder.CreateZExtOrTrunc(V,
Y->getType());
746 return BinaryOperator::CreateOr(
T, NewSel);
755 return BinaryOperator::CreateOr(
F, NewSel);
772 auto *CondVal =
SI.getCondition();
773 auto *TrueVal =
SI.getTrueValue();
774 auto *FalseVal =
SI.getFalseValue();
792 auto *TrueValC = dyn_cast<Constant>(TrueVal);
793 if (TrueValC ==
nullptr ||
795 !isa<Instruction>(FalseVal))
798 auto *ZeroC = cast<Constant>(cast<Instruction>(CondVal)->getOperand(1));
806 auto *FalseValI = cast<Instruction>(FalseVal);
809 IC.
replaceOperand(*FalseValI, FalseValI->getOperand(0) ==
Y ? 0 : 1, FrY);
817 const Value *TrueVal,
818 const Value *FalseVal,
838 return Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat,
A,
853 "Unexpected isUnsigned predicate!");
859 bool IsNegative =
false;
872 if (IsNegative && !TrueVal->hasOneUse() && !ICI->
hasOneUse())
877 Value *Result =
Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat,
A,
B);
879 Result =
Builder.CreateNeg(Result);
885 if (!Cmp->hasOneUse())
889 Value *Cmp0 = Cmp->getOperand(0);
890 Value *Cmp1 = Cmp->getOperand(1);
898 return Builder.CreateBinaryIntrinsic(
927 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat,
X,
Y);
937 return Builder.CreateBinaryIntrinsic(
947 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp1,
Y);
956 auto *TI = dyn_cast<Instruction>(TVal);
957 auto *FI = dyn_cast<Instruction>(FVal);
963 Value *
A = Cmp->getOperand(0);
964 Value *
B = Cmp->getOperand(1);
977 (TI->hasNoSignedWrap() || TI->hasNoUnsignedWrap()) &&
978 (FI->hasNoSignedWrap() || FI->hasNoUnsignedWrap())) {
985 TI->setHasNoUnsignedWrap(
false);
986 if (!TI->hasNoSignedWrap())
987 TI->setHasNoSignedWrap(TI->hasOneUse());
988 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, TI,
Builder.getTrue());
1012 if (!
match(FalseVal,
1016 if (!
match(TrueVal, m_Intrinsic<Intrinsic::ctlz>()))
1020 auto *II = cast<IntrinsicInst>(TrueVal);
1057 Value *Count =
nullptr;
1065 if (!
match(Count, m_Intrinsic<Intrinsic::cttz>(
m_Value(
X))) &&
1127 IntrinsicID = Intrinsic::umin;
1130 IntrinsicID = Intrinsic::umax;
1133 IntrinsicID = Intrinsic::smin;
1136 IntrinsicID = Intrinsic::smax;
1154 auto *
I = dyn_cast<Instruction>(V);
1158 bool Changed =
false;
1159 for (
Use &U :
I->operands()) {
1189 if (!
Cmp.isEquality())
1194 bool Swapped =
false;
1205 Value *CmpLHS =
Cmp.getOperand(0), *CmpRHS =
Cmp.getOperand(1);
1206 if (TrueVal != CmpLHS &&
1220 !
Cmp.getType()->isVectorTy())
1224 if (TrueVal != CmpRHS &&
1230 auto *FalseInst = dyn_cast<Instruction>(FalseVal);
1237 bool WasNUW =
false, WasNSW =
false, WasExact =
false, WasInBounds =
false;
1238 if (
auto *OBO = dyn_cast<OverflowingBinaryOperator>(FalseVal)) {
1239 WasNUW = OBO->hasNoUnsignedWrap();
1240 WasNSW = OBO->hasNoSignedWrap();
1241 FalseInst->setHasNoUnsignedWrap(
false);
1242 FalseInst->setHasNoSignedWrap(
false);
1244 if (
auto *PEO = dyn_cast<PossiblyExactOperator>(FalseVal)) {
1245 WasExact = PEO->isExact();
1246 FalseInst->setIsExact(
false);
1248 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(FalseVal)) {
1249 WasInBounds =
GEP->isInBounds();
1250 GEP->setIsInBounds(
false);
1258 false) == TrueVal ||
1260 false) == TrueVal) {
1266 FalseInst->setHasNoUnsignedWrap();
1268 FalseInst->setHasNoSignedWrap();
1270 FalseInst->setIsExact();
1272 cast<GetElementPtrInst>(FalseInst)->setIsInBounds();
1307 if (!isa<SelectInst>(Sel1)) {
1348 if (Cmp00->
getType() !=
X->getType() &&
X->hasOneUse())
1356 else if (!
match(Cmp00,
1364 Value *ReplacementLow, *ReplacementHigh;
1401 std::swap(ReplacementLow, ReplacementHigh);
1407 "Unexpected predicate type.");
1415 "Unexpected predicate type.");
1417 std::swap(ThresholdLowIncl, ThresholdHighExcl);
1433 if (
X->getType() != Sel0.
getType()) {
1443 Value *ShouldReplaceLow =
Builder.CreateICmpSLT(
X, ThresholdLowIncl);
1444 Value *ShouldReplaceHigh =
Builder.CreateICmpSGE(
X, ThresholdHighExcl);
1445 Value *MaybeReplacedLow =
1446 Builder.CreateSelect(ShouldReplaceLow, ReplacementLow,
X);
1451 ShouldReplaceHigh, ReplacementHigh, MaybeReplacedLow);
1495 Value *SelVal0, *SelVal1;
1504 auto MatchesSelectValue = [SelVal0, SelVal1](
Constant *
C) {
1505 return C->isElementWiseEqual(SelVal0) ||
C->isElementWiseEqual(SelVal1);
1509 if (MatchesSelectValue(C0))
1513 auto FlippedStrictness =
1515 if (!FlippedStrictness)
1519 if (!MatchesSelectValue(FlippedStrictness->second))
1528 Cmp.getName() +
".inv");
1539 if (!
Cmp->hasOneUse())
1569 Value *TVal =
SI.getTrueValue();
1570 Value *FVal =
SI.getFalseValue();
1574 return Builder.CreateBinaryIntrinsic(Intrinsic::umax, V, TVal);
1577 return Builder.CreateBinaryIntrinsic(Intrinsic::umin, V, TVal);
1580 return Builder.CreateBinaryIntrinsic(Intrinsic::smax, V, TVal);
1583 return Builder.CreateBinaryIntrinsic(Intrinsic::smin, V, TVal);
1596 const APInt *BinOpC;
1615 if (
Instruction *NewSPF = canonicalizeSPF(SI, *ICI, *
this))
1618 if (
Value *V = foldSelectInstWithICmpConst(SI, ICI,
Builder))
1621 if (
Value *V = canonicalizeClampLike(SI, *ICI,
Builder))
1625 tryToReuseConstantFromSelectInComparison(SI, *ICI, *
this))
1632 bool Changed =
false;
1638 if (CmpRHS != CmpLHS && isa<Constant>(CmpRHS) && !isa<Constant>(CmpLHS)) {
1641 SI.setOperand(1, CmpRHS);
1645 SI.setOperand(2, CmpRHS);
1662 SI.swapProfMetadata();
1668 if (
TrueVal->getType()->isIntOrIntVectorTy()) {
1675 bool IsBitTest =
false;
1683 Y = &MinSignedValue;
1685 TrueWhenUnset =
false;
1688 Y = &MinSignedValue;
1690 TrueWhenUnset =
true;
1695 if (TrueWhenUnset && TrueVal ==
X &&
1699 else if (!TrueWhenUnset && FalseVal ==
X &&
1703 else if (TrueWhenUnset && FalseVal ==
X &&
1707 else if (!TrueWhenUnset && TrueVal ==
X &&
1732 if (
Value *V = foldSelectCttzCtlz(ICI, TrueVal, FalseVal,
Builder))
1744 return Changed ? &
SI :
nullptr;
1756static bool canSelectOperandBeMappingIntoPredBlock(
const Value *V,
1761 if (!
I)
return true;
1765 const PHINode *CondPHI = cast<PHINode>(
SI.getCondition());
1767 if (
const PHINode *VP = dyn_cast<PHINode>(
I))
1768 if (VP->getParent() == CondPHI->
getParent())
1792 if (
C ==
A ||
C ==
B) {
1807 Value *CondVal =
SI.getCondition();
1810 auto *TI = dyn_cast<Instruction>(TrueVal);
1811 auto *FI = dyn_cast<Instruction>(FalseVal);
1812 if (!TI || !FI || !TI->hasOneUse() || !FI->hasOneUse())
1816 if ((TI->getOpcode() == Instruction::Sub &&
1817 FI->getOpcode() == Instruction::Add) ||
1818 (TI->getOpcode() == Instruction::FSub &&
1819 FI->getOpcode() == Instruction::FAdd)) {
1822 }
else if ((FI->getOpcode() == Instruction::Sub &&
1823 TI->getOpcode() == Instruction::Add) ||
1824 (FI->getOpcode() == Instruction::FSub &&
1825 TI->getOpcode() == Instruction::FAdd)) {
1831 Value *OtherAddOp =
nullptr;
1832 if (SubOp->getOperand(0) == AddOp->
getOperand(0)) {
1834 }
else if (SubOp->getOperand(0) == AddOp->
getOperand(1)) {
1842 if (
SI.getType()->isFPOrFPVectorTy()) {
1843 NegVal =
Builder.CreateFNeg(SubOp->getOperand(1));
1844 if (
Instruction *NegInst = dyn_cast<Instruction>(NegVal)) {
1846 Flags &= SubOp->getFastMathFlags();
1847 NegInst->setFastMathFlags(Flags);
1850 NegVal =
Builder.CreateNeg(SubOp->getOperand(1));
1853 Value *NewTrueOp = OtherAddOp;
1854 Value *NewFalseOp = NegVal;
1857 Value *NewSel =
Builder.CreateSelect(CondVal, NewTrueOp, NewFalseOp,
1858 SI.getName() +
".p", &SI);
1860 if (
SI.getType()->isFPOrFPVectorTy()) {
1862 BinaryOperator::CreateFAdd(SubOp->getOperand(0), NewSel);
1865 Flags &= SubOp->getFastMathFlags();
1869 return BinaryOperator::CreateAdd(SubOp->getOperand(0), NewSel);
1882 Value *CondVal =
SI.getCondition();
1894 auto IsSignedSaturateLimit = [&](
Value *Limit,
bool IsAdd) {
1904 auto IsZeroOrOne = [](
const APInt &
C) {
return C.isZero() ||
C.isOne(); };
1912 if (Op !=
X && Op !=
Y)
1921 IsMinMax(TrueVal, FalseVal))
1928 IsMinMax(FalseVal, TrueVal))
1934 IsMinMax(TrueVal, FalseVal))
1939 IsMinMax(FalseVal, TrueVal))
1944 IsMinMax(FalseVal, TrueVal))
1949 IsMinMax(TrueVal, FalseVal))
1960 NewIntrinsicID = Intrinsic::uadd_sat;
1961 else if (II->
getIntrinsicID() == Intrinsic::usub_with_overflow &&
1964 NewIntrinsicID = Intrinsic::usub_sat;
1965 else if (II->
getIntrinsicID() == Intrinsic::sadd_with_overflow &&
1966 IsSignedSaturateLimit(TrueVal,
true))
1975 NewIntrinsicID = Intrinsic::sadd_sat;
1976 else if (II->
getIntrinsicID() == Intrinsic::ssub_with_overflow &&
1977 IsSignedSaturateLimit(TrueVal,
false))
1986 NewIntrinsicID = Intrinsic::ssub_sat;
2007 if (ExtOpcode != Instruction::ZExt && ExtOpcode != Instruction::SExt)
2013 Type *SmallType =
X->getType();
2015 auto *
Cmp = dyn_cast<CmpInst>(
Cond);
2017 (!Cmp ||
Cmp->getOperand(0)->getType() != SmallType))
2026 Value *TruncCVal = cast<Value>(TruncC);
2059 Value *CondVal =
SI.getCondition();
2061 auto *CondValTy = dyn_cast<FixedVectorType>(CondVal->
getType());
2065 unsigned NumElts = CondValTy->getNumElements();
2067 Mask.reserve(NumElts);
2068 for (
unsigned i = 0; i != NumElts; ++i) {
2078 Mask.push_back(i + NumElts);
2079 }
else if (isa<UndefValue>(Elt)) {
2099 auto *Ty = dyn_cast<VectorType>(Sel.
getType());
2131 if (TVal ==
A || TVal ==
B || FVal ==
A || FVal ==
B)
2148 if (TSrc ==
C && FSrc ==
D) {
2152 }
else if (TSrc ==
D && FSrc ==
C) {
2191 auto *Extract = dyn_cast<ExtractValueInst>(V);
2194 if (Extract->getIndices()[0] !=
I)
2196 return dyn_cast<AtomicCmpXchgInst>(Extract->getAggregateOperand());
2202 if (
auto *
Select = dyn_cast<SelectInst>(
SI.user_back()))
2203 if (
Select->getCondition() ==
SI.getCondition())
2204 if (
Select->getFalseValue() ==
SI.getTrueValue() ||
2205 Select->getTrueValue() ==
SI.getFalseValue())
2209 auto *CmpXchg = isExtractFromCmpXchg(
SI.getCondition(), 1);
2216 if (
auto *
X = isExtractFromCmpXchg(
SI.getTrueValue(), 0))
2217 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getFalseValue())
2218 return SI.getFalseValue();
2223 if (
auto *
X = isExtractFromCmpXchg(
SI.getFalseValue(), 0))
2224 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getTrueValue())
2225 return SI.getFalseValue();
2249 Value *SV0, *SV1, *SA0, *SA1;
2258 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2264 Or1->
getOpcode() == BinaryOperator::LShr &&
2265 "Illegal or(shift,shift) pair");
2280 bool IsFshl = (ShAmt == SA0);
2282 if ((IsFshl && TVal != SV0) || (!IsFshl && TVal != SV1))
2296 SV1 =
Builder.CreateFreeze(SV1);
2298 SV0 =
Builder.CreateFreeze(SV0);
2303 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
2324 assert(TC != FC &&
"Expected equal select arms to simplify");
2328 bool IsTrueIfSignSet;
2332 X->getType() != SelType)
2353 if (!isa<VectorType>(Sel.
getType()))
2364 if (
auto *
I = dyn_cast<Instruction>(V))
2365 I->copyIRFlags(&Sel);
2368 M, Intrinsic::experimental_vector_reverse,
V->getType());
2376 return createSelReverse(
C,
X,
Y);
2380 return createSelReverse(
C,
X, FVal);
2385 return createSelReverse(
C, TVal,
Y);
2388 auto *VecTy = dyn_cast<FixedVectorType>(Sel.
getType());
2392 unsigned NumElts = VecTy->getNumElements();
2393 APInt UndefElts(NumElts, 0);
2407 cast<ShuffleVectorInst>(TVal)->isSelect()) {
2421 cast<ShuffleVectorInst>(FVal)->isSelect()) {
2442 auto *IDomNode = DT[BB]->getIDom();
2448 Value *IfTrue, *IfFalse;
2464 if (TrueSucc == FalseSucc)
2480 else if (DT.
dominates(FalseEdge, Incoming))
2485 if (
auto *
Insn = dyn_cast<Instruction>(Inputs[Pred]))
2493 PN->addIncoming(Inputs[Pred], Pred);
2504 if (
auto *
I = dyn_cast<Instruction>(V))
2505 CandidateBlocks.
insert(
I->getParent());
2508 if (
auto *PN = foldSelectToPhiImpl(Sel, BB, DT, Builder))
2542 Value *CondVal =
SI.getCondition();
2546 assert(
Op->getType()->isIntOrIntVectorTy(1) &&
2547 "Op must be either i1 or vector of i1.");
2585 Value *CondVal =
SI.getCondition();
2587 bool ChangedFMF =
false;
2588 for (
bool Swap : {
false,
true}) {
2618 FastMathFlags FMF = cast<FPMathOperator>(TrueVal)->getFastMathFlags();
2619 if (FMF.
noNaNs() && !
SI.hasNoNaNs()) {
2620 SI.setHasNoNaNs(
true);
2623 if (FMF.
noInfs() && !
SI.hasNoInfs()) {
2624 SI.setHasNoInfs(
true);
2638 if (!
SI.hasNoSignedZeros() || !
SI.hasNoNaNs())
2655 Instruction *NewFNeg = UnaryOperator::CreateFNeg(Fabs);
2661 return ChangedFMF ? &
SI :
nullptr;
2679foldRoundUpIntegerWithPow2Alignment(
SelectInst &SI,
2683 Value *XBiasedHighBits =
SI.getFalseValue();
2696 const APInt *LowBitMaskCst;
2701 const APInt *BiasCst, *HighBitMaskCst;
2702 if (!
match(XBiasedHighBits,
2705 !
match(XBiasedHighBits,
2710 if (!LowBitMaskCst->
isMask())
2713 APInt InvertedLowBitMaskCst = ~*LowBitMaskCst;
2714 if (InvertedLowBitMaskCst != *HighBitMaskCst)
2717 APInt AlignmentCst = *LowBitMaskCst + 1;
2719 if (*BiasCst != AlignmentCst && *BiasCst != *LowBitMaskCst)
2723 if (*BiasCst == *LowBitMaskCst)
2724 return XBiasedHighBits;
2729 Type *Ty =
X->getType();
2731 X->getName() +
".biased");
2738struct DecomposedSelect {
2755 DecomposedSelect OuterSel;
2762 std::swap(OuterSel.TrueVal, OuterSel.FalseVal);
2770 Value *InnerSelVal = IsAndVariant ? OuterSel.FalseVal : OuterSel.TrueVal;
2774 [](
Value *V) {
return V->hasOneUse(); }))
2778 DecomposedSelect InnerSel;
2779 if (!
match(InnerSelVal,
2786 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
2788 Value *AltCond =
nullptr;
2789 auto matchOuterCond = [OuterSel, &AltCond](
auto m_InnerCond) {
2797 if (matchOuterCond(
m_Specific(InnerSel.Cond))) {
2802 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
2803 InnerSel.Cond = NotInnerCond;
2808 AltCond, IsAndVariant ? OuterSel.TrueVal : InnerSel.FalseVal,
2809 IsAndVariant ? InnerSel.TrueVal : OuterSel.FalseVal);
2812 IsAndVariant ? SelInner : InnerSel.TrueVal,
2813 !IsAndVariant ? SelInner : InnerSel.FalseVal);
2817 Value *CondVal =
SI.getCondition();
2820 Type *SelType =
SI.getType();
2839 return BinaryOperator::CreateOr(CondVal, FalseVal);
2842 if (
auto *LHS = dyn_cast<FCmpInst>(CondVal))
2843 if (
auto *RHS = dyn_cast<FCmpInst>(FalseVal))
2844 if (
Value *V = foldLogicOfFCmps(LHS, RHS,
false,
2852 bool CondLogicAnd = isa<SelectInst>(CondVal);
2853 bool FalseLogicAnd = isa<SelectInst>(FalseVal);
2854 auto AndFactorization = [&](
Value *Common,
Value *InnerCond,
2860 if (FalseLogicAnd || (CondLogicAnd && Common ==
A))
2863 return BinaryOperator::CreateAnd(Common, InnerSel);
2867 return AndFactorization(
A,
B,
D);
2869 return AndFactorization(
A,
B,
C);
2871 return AndFactorization(
B,
A,
D);
2873 return AndFactorization(
B,
A,
C, CondLogicAnd && FalseLogicAnd);
2880 return BinaryOperator::CreateAnd(CondVal, TrueVal);
2883 if (
auto *LHS = dyn_cast<FCmpInst>(CondVal))
2884 if (
auto *RHS = dyn_cast<FCmpInst>(TrueVal))
2885 if (
Value *V = foldLogicOfFCmps(LHS, RHS,
true,
2893 bool CondLogicOr = isa<SelectInst>(CondVal);
2894 bool TrueLogicOr = isa<SelectInst>(TrueVal);
2895 auto OrFactorization = [&](
Value *Common,
Value *InnerCond,
2901 if (TrueLogicOr || (CondLogicOr && Common ==
A))
2904 return BinaryOperator::CreateOr(Common, InnerSel);
2908 return OrFactorization(
A,
B,
D);
2910 return OrFactorization(
A,
B,
C);
2912 return OrFactorization(
B,
A,
D);
2914 return OrFactorization(
B,
A,
C, CondLogicOr && TrueLogicOr);
2965 return BinaryOperator::CreateXor(
A,
B);
2985 auto *FI =
new FreezeInst(*
Y, (*Y)->getName() +
".fr");
2991 if (
auto *Op1SI = dyn_cast<SelectInst>(Op1))
2992 if (
auto *
I = foldAndOrOfSelectUsingImpliedCond(CondVal, *Op1SI,
2996 if (
auto *ICmp0 = dyn_cast<ICmpInst>(CondVal))
2997 if (
auto *ICmp1 = dyn_cast<ICmpInst>(Op1))
2998 if (
auto *V = foldAndOrOfICmps(ICmp0, ICmp1, SI, IsAnd,
3009 if (Res && *Res ==
false)
3015 if (Res && *Res ==
false)
3024 if (Res && *Res ==
true)
3030 if (Res && *Res ==
true)
3043 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3044 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3045 bool MayNeedFreeze = SelCond && SelFVal &&
3046 match(SelFVal->getTrueValue(),
3059 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3060 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3061 bool MayNeedFreeze = SelCond && SelFVal &&
3062 match(SelCond->getTrueValue(),
3104 auto MatchForward = [&](
Value *CommonAncestor) {
3105 const APInt *
C =
nullptr;
3106 if (CtlzOp == CommonAncestor)
3123 const APInt *
C =
nullptr;
3124 Value *CommonAncestor;
3125 if (MatchForward(Cond0)) {
3129 if (!MatchForward(CommonAncestor))
3166 Type *SelType =
SI.getType();
3173 Value *Cond0, *Ctlz, *CtlzOp;
3187 !isSafeToRemoveBitCeilSelect(Pred, Cond0, Cond1, CtlzOp,
BitWidth))
3202 Value *CondVal =
SI.getCondition();
3205 Type *SelType =
SI.getType();
3214 if (
Instruction *
I = canonicalizeScalarSelectOfVecs(SI, *
this))
3272 return new ZExtInst(CondVal, SelType);
3276 return new SExtInst(CondVal, SelType);
3281 return new ZExtInst(NotCond, SelType);
3287 return new SExtInst(NotCond, SelType);
3291 if (
auto *FCmp = dyn_cast<FCmpInst>(CondVal)) {
3294 if ((Cmp0 == TrueVal && Cmp1 == FalseVal) ||
3295 (Cmp0 == FalseVal && Cmp1 == TrueVal)) {
3307 FCmp->getName() +
".inv");
3314 if (isa<FPMathOperator>(SI)) {
3319 if (
SI.hasNoNaNs() &&
SI.hasNoSignedZeros()) {
3332 if (
Instruction *Fabs = foldSelectWithFCmpToFabs(SI, *
this))
3336 if (
ICmpInst *ICI = dyn_cast<ICmpInst>(CondVal))
3350 auto *TI = dyn_cast<Instruction>(TrueVal);
3351 auto *FI = dyn_cast<Instruction>(FalseVal);
3352 if (TI && FI && TI->getOpcode() == FI->
getOpcode())
3368 if (isa<VectorType>(CondVal->
getType()) && !isa<VectorType>(
Idx->getType()))
3379 if (
auto *TrueGep = dyn_cast<GetElementPtrInst>(TrueVal))
3380 if (
auto *NewGep = SelectGepWithBase(TrueGep, FalseVal,
false))
3382 if (
auto *FalseGep = dyn_cast<GetElementPtrInst>(FalseVal))
3383 if (
auto *NewGep = SelectGepWithBase(FalseGep, TrueVal,
true))
3399 RHS2, SI, SPF, RHS))
3403 RHS2, SI, SPF, LHS))
3412 bool IsCastNeeded =
LHS->
getType() != SelType;
3413 Value *CmpLHS = cast<CmpInst>(CondVal)->getOperand(0);
3414 Value *CmpRHS = cast<CmpInst>(CondVal)->getOperand(1);
3417 ((CmpLHS != LHS && CmpLHS != RHS) ||
3418 (CmpRHS != LHS && CmpRHS != RHS)))) {
3427 cast<FPMathOperator>(
SI.getCondition())->getFastMathFlags();
3443 if (
auto *PN = dyn_cast<PHINode>(
SI.getCondition()))
3445 if (canSelectOperandBeMappingIntoPredBlock(TrueVal, SI) &&
3446 canSelectOperandBeMappingIntoPredBlock(FalseVal, SI))
3450 if (
SelectInst *TrueSI = dyn_cast<SelectInst>(TrueVal)) {
3451 if (TrueSI->getCondition()->getType() == CondVal->
getType()) {
3453 if (TrueSI->getCondition() == CondVal) {
3454 if (
SI.getTrueValue() == TrueSI->getTrueValue())
3462 if (TrueSI->getFalseValue() == FalseVal && TrueSI->hasOneUse()) {
3470 if (
SelectInst *FalseSI = dyn_cast<SelectInst>(FalseVal)) {
3471 if (FalseSI->getCondition()->getType() == CondVal->
getType()) {
3473 if (FalseSI->getCondition() == CondVal) {
3474 if (
SI.getFalseValue() == FalseSI->getFalseValue())
3479 if (FalseSI->getTrueValue() == TrueVal && FalseSI->hasOneUse()) {
3496 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(0))) {
3497 if (TrueBOSI->getCondition() == CondVal) {
3503 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(1))) {
3504 if (TrueBOSI->getCondition() == CondVal) {
3515 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(0))) {
3516 if (FalseBOSI->getCondition() == CondVal) {
3522 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(1))) {
3523 if (FalseBOSI->getCondition() == CondVal) {
3536 SI.swapProfMetadata();
3551 if (Known.One.isOne())
3553 if (Known.Zero.isOne())
3561 if (
Value *V = foldSelectCmpXchg(SI))
3579 if (
Value *V = foldRoundUpIntegerWithPow2Alignment(SI,
Builder))
3589 auto *MaskedInst = cast<IntrinsicInst>(TrueVal);
3590 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
3591 MaskedInst->setArgOperand(3, FalseVal );
3606 bool CanMergeSelectIntoLoad =
false;
3610 if (CanMergeSelectIntoLoad) {
3611 auto *MaskedInst = cast<IntrinsicInst>(FalseVal);
3612 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
3613 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 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 * 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.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
bool isMinSignedValue() const
Determine if this is the smallest signed 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 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=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 * 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.
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.
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.
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 * 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.
bool replaceInInstruction(Value *V, Value *Old, Value *New, unsigned Depth=0)
Instruction * foldSelectInstWithICmp(SelectInst &SI, ICmpInst *ICI)
bool sinkNotIntoOtherHandOfLogicalOp(Instruction &I)
Instruction * foldSelectIntoOp(SelectInst &SI, Value *, Value *)
Try to fold the select into one of the operands to allow further optimization.
Instruction * visitSelectInst(SelectInst &SI)
Instruction * foldSelectOfBools(SelectInst &SI)
Instruction * foldSelectExtConst(SelectInst &Sel)
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 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.
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.
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.
#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.
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.