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))
123 const APInt *SelTC, *SelFC;
130 if (SelType->
isVectorTy() != Cmp->getType()->isVectorTy())
135 bool CreateAnd =
false;
141 V = Cmp->getOperand(0);
164 if (!TC.
isZero() && !FC.isZero()) {
173 if (!Cmp->hasOneUse())
177 bool ExtraBitInTC = TC.
ugt(FC);
178 if (Pred == ICmpInst::ICMP_EQ) {
185 if (Pred == ICmpInst::ICMP_NE) {
202 unsigned ValZeros = ValC.
logBase2();
203 unsigned AndZeros = AndMask.
logBase2();
211 if (ValZeros > AndZeros) {
213 V = Builder.
CreateShl(V, ValZeros - AndZeros);
214 }
else if (ValZeros < AndZeros) {
215 V = Builder.
CreateLShr(V, AndZeros - ValZeros);
223 bool ShouldNotVal = !TC.
isZero();
224 ShouldNotVal ^= Pred == ICmpInst::ICMP_NE;
242 switch (
I->getOpcode()) {
243 case Instruction::Add:
244 case Instruction::FAdd:
245 case Instruction::Mul:
246 case Instruction::FMul:
247 case Instruction::And:
248 case Instruction::Or:
249 case Instruction::Xor:
251 case Instruction::Sub:
252 case Instruction::FSub:
253 case Instruction::FDiv:
254 case Instruction::Shl:
255 case Instruction::LShr:
256 case Instruction::AShr:
286 if (
auto *CondVTy = dyn_cast<VectorType>(CondTy)) {
288 CondVTy->getElementCount() !=
289 cast<VectorType>(FIOpndTy)->getElementCount())
300 if (TI->
getOpcode() != Instruction::BitCast &&
313 SI.getName() +
".v", &SI);
318 Value *OtherOpT, *OtherOpF;
321 bool Swapped =
false) ->
Value * {
322 assert(!(Commute && Swapped) &&
323 "Commute and Swapped can't set at the same time");
328 MatchIsOpZero =
true;
333 MatchIsOpZero =
false;
338 if (!Commute && !Swapped)
347 MatchIsOpZero =
true;
352 MatchIsOpZero =
false;
366 FMF |= SI.getFastMathFlags();
369 if (
auto *NewSelI = dyn_cast<Instruction>(NewSel))
370 NewSelI->setFastMathFlags(FMF);
371 Instruction *NewFNeg = UnaryOperator::CreateFNeg(NewSel);
380 auto *
TII = dyn_cast<IntrinsicInst>(TI);
381 auto *FII = dyn_cast<IntrinsicInst>(FI);
382 if (
TII && FII &&
TII->getIntrinsicID() == FII->getIntrinsicID()) {
384 if (
Value *MatchOp = getCommonOp(TI, FI,
true)) {
396 if (
TII->getIntrinsicID() == Intrinsic::ldexp) {
397 Value *LdexpVal0 =
TII->getArgOperand(0);
398 Value *LdexpExp0 =
TII->getArgOperand(1);
399 Value *LdexpVal1 = FII->getArgOperand(0);
400 Value *LdexpExp1 = FII->getArgOperand(1);
404 FMF &= cast<FPMathOperator>(FII)->getFastMathFlags();
411 TII->
getType(), Intrinsic::ldexp, {SelectVal, SelectExp});
424 bool Swapped = TPred != FPred;
428 SI.getName() +
".v", &SI);
443 (!isa<BinaryOperator>(TI) && !isa<GetElementPtrInst>(TI)) ||
465 auto *BO = dyn_cast<BinaryOperator>(TI);
469 if (BO->getOpcode() == Instruction::SDiv ||
470 BO->getOpcode() == Instruction::SRem || MatchIsOpZero)
476 SI.getName() +
".v", &SI);
477 Value *Op0 = MatchIsOpZero ? MatchOp : NewSI;
478 Value *Op1 = MatchIsOpZero ? NewSI : MatchOp;
479 if (
auto *BO = dyn_cast<BinaryOperator>(TI)) {
485 if (
auto *TGEP = dyn_cast<GetElementPtrInst>(TI)) {
486 auto *FGEP = cast<GetElementPtrInst>(FI);
487 Type *ElementType = TGEP->getResultElementType();
488 return TGEP->isInBounds() && FGEP->isInBounds()
511 auto *TVI = dyn_cast<BinaryOperator>(TrueVal);
512 if (!TVI || !TVI->hasOneUse() || isa<Constant>(FalseVal))
516 unsigned OpToFold = 0;
517 if ((SFO & 1) && FalseVal == TVI->getOperand(0))
519 else if ((SFO & 2) && FalseVal == TVI->getOperand(1))
529 if (isa<FPMathOperator>(&SI))
530 FMF = SI.getFastMathFlags();
532 TVI->getOpcode(), TVI->getType(),
true, FMF.
noSignedZeros());
533 Value *OOp = TVI->getOperand(2 - OpToFold);
538 if (!isa<Constant>(OOp) ||
539 (OOpIsAPInt &&
isSelect01(
C->getUniqueInteger(), *OOpC))) {
541 Swapped ? OOp :
C,
"", &SI);
542 if (isa<FPMathOperator>(&SI))
543 cast<Instruction>(NewSel)->setFastMathFlags(FMF);
553 if (
Instruction *R = TryFoldSelectIntoOp(SI, TrueVal, FalseVal,
false))
556 if (
Instruction *R = TryFoldSelectIntoOp(SI, FalseVal, TrueVal,
true))
573 if (!(Cmp->hasOneUse() && Cmp->getOperand(0)->hasOneUse() &&
610 return new ZExtInst(ICmpNeZero, SelType);
632 const APInt *C2, *C1;
642 auto *FI = dyn_cast<Instruction>(FVal);
646 FI->setHasNoSignedWrap(
false);
647 FI->setHasNoUnsignedWrap(
false);
682 const auto *Ashr = cast<Instruction>(FalseVal);
684 bool IsExact = Ashr->isExact() && cast<Instruction>(TrueVal)->isExact();
716 if (!TrueVal->getType()->isIntOrIntVectorTy() ||
751 BinOp = cast<BinaryOperator>(FalseVal);
755 BinOp = cast<BinaryOperator>(TrueVal);
765 if (IdentityC ==
nullptr || !IdentityC->isNullValue())
770 bool NeedShift = C1Log != C2Log;
771 bool NeedZExtTrunc =
Y->getType()->getScalarSizeInBits() !=
772 V->getType()->getScalarSizeInBits();
775 if ((NeedShift + NeedXor + NeedZExtTrunc +
NeedAnd) >
788 }
else if (C1Log > C2Log) {
817 return BinaryOperator::CreateOr(
T, NewSel);
826 return BinaryOperator::CreateOr(
F, NewSel);
843 auto *CondVal = SI.getCondition();
844 auto *TrueVal = SI.getTrueValue();
845 auto *FalseVal = SI.getFalseValue();
863 auto *TrueValC = dyn_cast<Constant>(TrueVal);
864 if (TrueValC ==
nullptr ||
866 !isa<Instruction>(FalseVal))
869 auto *ZeroC = cast<Constant>(cast<Instruction>(CondVal)->getOperand(1));
877 auto *FalseValI = cast<Instruction>(FalseVal);
880 IC.
replaceOperand(*FalseValI, FalseValI->getOperand(0) ==
Y ? 0 : 1, FrY);
888 const Value *TrueVal,
889 const Value *FalseVal,
924 "Unexpected isUnsigned predicate!");
930 bool IsNegative =
false;
943 if (IsNegative && !TrueVal->hasOneUse() && !ICI->
hasOneUse())
956 if (!Cmp->hasOneUse())
960 Value *Cmp0 = Cmp->getOperand(0);
961 Value *Cmp1 = Cmp->getOperand(1);
1027 auto *TI = dyn_cast<Instruction>(TVal);
1028 auto *FI = dyn_cast<Instruction>(FVal);
1034 Value *
A = Cmp->getOperand(0);
1035 Value *
B = Cmp->getOperand(1);
1048 (TI->hasNoSignedWrap() || TI->hasNoUnsignedWrap()) &&
1049 (FI->hasNoSignedWrap() || FI->hasNoUnsignedWrap())) {
1056 TI->setHasNoUnsignedWrap(
false);
1057 if (!TI->hasNoSignedWrap())
1058 TI->setHasNoSignedWrap(TI->hasOneUse());
1086 if (!
match(FalseVal,
1090 if (!
match(Ctlz, m_Intrinsic<Intrinsic::ctlz>()))
1097 auto *II = cast<IntrinsicInst>(Ctlz);
1134 Value *Count =
nullptr;
1142 if (!
match(Count, m_Intrinsic<Intrinsic::cttz>(
m_Value(
X))) &&
1204 IntrinsicID = Intrinsic::umin;
1207 IntrinsicID = Intrinsic::umax;
1210 IntrinsicID = Intrinsic::smin;
1213 IntrinsicID = Intrinsic::smax;
1231 auto *
I = dyn_cast<Instruction>(V);
1235 bool Changed =
false;
1236 for (
Use &U :
I->operands()) {
1266 if (!
Cmp.isEquality())
1271 bool Swapped =
false;
1282 Value *CmpLHS =
Cmp.getOperand(0), *CmpRHS =
Cmp.getOperand(1);
1283 if (TrueVal != CmpLHS &&
1297 !
Cmp.getType()->isVectorTy())
1301 if (TrueVal != CmpRHS &&
1307 auto *FalseInst = dyn_cast<Instruction>(FalseVal);
1322 &DropFlags) == TrueVal ||
1325 &DropFlags) == TrueVal) {
1327 I->dropPoisonGeneratingFlagsAndMetadata();
1367 if (!isa<SelectInst>(Sel1)) {
1408 if (Cmp00->
getType() !=
X->getType() &&
X->hasOneUse())
1416 else if (!
match(Cmp00,
1424 Value *ReplacementLow, *ReplacementHigh;
1461 std::swap(ReplacementLow, ReplacementHigh);
1467 "Unexpected predicate type.");
1475 "Unexpected predicate type.");
1477 std::swap(ThresholdLowIncl, ThresholdHighExcl);
1493 if (
X->getType() != Sel0.
getType()) {
1503 assert(ReplacementLow && ReplacementHigh &&
1504 "Constant folding of ImmConstant cannot fail");
1510 Value *MaybeReplacedLow =
1516 ShouldReplaceHigh, ReplacementHigh, MaybeReplacedLow);
1560 Value *SelVal0, *SelVal1;
1569 auto MatchesSelectValue = [SelVal0, SelVal1](
Constant *
C) {
1570 return C->isElementWiseEqual(SelVal0) ||
C->isElementWiseEqual(SelVal1);
1574 if (MatchesSelectValue(C0))
1578 auto FlippedStrictness =
1580 if (!FlippedStrictness)
1584 if (!MatchesSelectValue(FlippedStrictness->second))
1593 Cmp.getName() +
".inv");
1604 if (!
Cmp->hasOneUse())
1634 Value *TVal =
SI.getTrueValue();
1635 Value *FVal =
SI.getFalseValue();
1661 const APInt *BinOpC;
1680 if (
Instruction *NewSPF = canonicalizeSPF(SI, *ICI, *
this))
1683 if (
Value *V = foldSelectInstWithICmpConst(SI, ICI,
Builder))
1686 if (
Value *V = canonicalizeClampLike(SI, *ICI,
Builder))
1690 tryToReuseConstantFromSelectInComparison(SI, *ICI, *
this))
1697 bool Changed =
false;
1703 if (CmpRHS != CmpLHS && isa<Constant>(CmpRHS) && !isa<Constant>(CmpLHS)) {
1706 SI.setOperand(1, CmpRHS);
1710 SI.setOperand(2, CmpRHS);
1727 SI.swapProfMetadata();
1733 if (
TrueVal->getType()->isIntOrIntVectorTy()) {
1740 bool IsBitTest =
false;
1748 Y = &MinSignedValue;
1750 TrueWhenUnset =
false;
1753 Y = &MinSignedValue;
1755 TrueWhenUnset =
true;
1760 if (TrueWhenUnset && TrueVal ==
X &&
1764 else if (!TrueWhenUnset && FalseVal ==
X &&
1768 else if (TrueWhenUnset && FalseVal ==
X &&
1772 else if (!TrueWhenUnset && TrueVal ==
X &&
1800 if (
Value *V = foldSelectCttzCtlz(ICI, TrueVal, FalseVal,
Builder))
1812 return Changed ? &
SI :
nullptr;
1824static bool canSelectOperandBeMappingIntoPredBlock(
const Value *V,
1829 if (!
I)
return true;
1833 const PHINode *CondPHI = cast<PHINode>(
SI.getCondition());
1835 if (
const PHINode *VP = dyn_cast<PHINode>(
I))
1836 if (VP->getParent() == CondPHI->
getParent())
1860 if (
C ==
A ||
C ==
B) {
1875 Value *CondVal =
SI.getCondition();
1878 auto *TI = dyn_cast<Instruction>(TrueVal);
1879 auto *FI = dyn_cast<Instruction>(FalseVal);
1880 if (!TI || !FI || !TI->hasOneUse() || !FI->hasOneUse())
1884 if ((TI->getOpcode() == Instruction::Sub &&
1885 FI->getOpcode() == Instruction::Add) ||
1886 (TI->getOpcode() == Instruction::FSub &&
1887 FI->getOpcode() == Instruction::FAdd)) {
1890 }
else if ((FI->getOpcode() == Instruction::Sub &&
1891 TI->getOpcode() == Instruction::Add) ||
1892 (FI->getOpcode() == Instruction::FSub &&
1893 TI->getOpcode() == Instruction::FAdd)) {
1899 Value *OtherAddOp =
nullptr;
1900 if (SubOp->getOperand(0) == AddOp->
getOperand(0)) {
1902 }
else if (SubOp->getOperand(0) == AddOp->
getOperand(1)) {
1910 if (
SI.getType()->isFPOrFPVectorTy()) {
1911 NegVal = Builder.
CreateFNeg(SubOp->getOperand(1));
1912 if (
Instruction *NegInst = dyn_cast<Instruction>(NegVal)) {
1914 Flags &= SubOp->getFastMathFlags();
1915 NegInst->setFastMathFlags(Flags);
1918 NegVal = Builder.
CreateNeg(SubOp->getOperand(1));
1921 Value *NewTrueOp = OtherAddOp;
1922 Value *NewFalseOp = NegVal;
1926 SI.getName() +
".p", &SI);
1928 if (
SI.getType()->isFPOrFPVectorTy()) {
1930 BinaryOperator::CreateFAdd(SubOp->getOperand(0), NewSel);
1933 Flags &= SubOp->getFastMathFlags();
1937 return BinaryOperator::CreateAdd(SubOp->getOperand(0), NewSel);
1950 Value *CondVal =
SI.getCondition();
1962 auto IsSignedSaturateLimit = [&](
Value *Limit,
bool IsAdd) {
1972 auto IsZeroOrOne = [](
const APInt &
C) {
return C.isZero() ||
C.isOne(); };
1989 IsMinMax(TrueVal, FalseVal))
1996 IsMinMax(FalseVal, TrueVal))
2002 IsMinMax(TrueVal, FalseVal))
2007 IsMinMax(FalseVal, TrueVal))
2012 IsMinMax(FalseVal, TrueVal))
2017 IsMinMax(TrueVal, FalseVal))
2028 NewIntrinsicID = Intrinsic::uadd_sat;
2029 else if (II->
getIntrinsicID() == Intrinsic::usub_with_overflow &&
2032 NewIntrinsicID = Intrinsic::usub_sat;
2033 else if (II->
getIntrinsicID() == Intrinsic::sadd_with_overflow &&
2034 IsSignedSaturateLimit(TrueVal,
true))
2043 NewIntrinsicID = Intrinsic::sadd_sat;
2044 else if (II->
getIntrinsicID() == Intrinsic::ssub_with_overflow &&
2045 IsSignedSaturateLimit(TrueVal,
false))
2054 NewIntrinsicID = Intrinsic::ssub_sat;
2075 if (ExtOpcode != Instruction::ZExt && ExtOpcode != Instruction::SExt)
2081 Type *SmallType =
X->getType();
2083 auto *
Cmp = dyn_cast<CmpInst>(
Cond);
2085 (!Cmp ||
Cmp->getOperand(0)->getType() != SmallType))
2093 Value *TruncCVal = cast<Value>(TruncC);
2109 Value *CondVal =
SI.getCondition();
2111 auto *CondValTy = dyn_cast<FixedVectorType>(CondVal->
getType());
2115 unsigned NumElts = CondValTy->getNumElements();
2117 Mask.reserve(NumElts);
2118 for (
unsigned i = 0; i != NumElts; ++i) {
2128 Mask.push_back(i + NumElts);
2129 }
else if (isa<UndefValue>(Elt)) {
2149 auto *Ty = dyn_cast<VectorType>(Sel.
getType());
2181 if (TVal ==
A || TVal ==
B || FVal ==
A || FVal ==
B)
2198 if (TSrc ==
C && FSrc ==
D) {
2202 }
else if (TSrc ==
D && FSrc ==
C) {
2241 auto *Extract = dyn_cast<ExtractValueInst>(V);
2244 if (Extract->getIndices()[0] !=
I)
2246 return dyn_cast<AtomicCmpXchgInst>(Extract->getAggregateOperand());
2252 if (
auto *
Select = dyn_cast<SelectInst>(
SI.user_back()))
2253 if (
Select->getCondition() ==
SI.getCondition())
2254 if (
Select->getFalseValue() ==
SI.getTrueValue() ||
2255 Select->getTrueValue() ==
SI.getFalseValue())
2259 auto *CmpXchg = isExtractFromCmpXchg(
SI.getCondition(), 1);
2266 if (
auto *
X = isExtractFromCmpXchg(
SI.getTrueValue(), 0))
2267 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getFalseValue())
2268 return SI.getFalseValue();
2273 if (
auto *
X = isExtractFromCmpXchg(
SI.getFalseValue(), 0))
2274 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getTrueValue())
2275 return SI.getFalseValue();
2299 Value *SV0, *SV1, *SA0, *SA1;
2308 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2314 Or1->
getOpcode() == BinaryOperator::LShr &&
2315 "Illegal or(shift,shift) pair");
2330 bool IsFshl = (ShAmt == SA0);
2332 if ((IsFshl && TVal != SV0) || (!IsFshl && TVal != SV1))
2353 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
2374 assert(TC != FC &&
"Expected equal select arms to simplify");
2378 bool IsTrueIfSignSet;
2382 X->getType() != SelType)
2403 if (!isa<VectorType>(Sel.
getType()))
2414 if (
auto *
I = dyn_cast<Instruction>(V))
2415 I->copyIRFlags(&Sel);
2418 M, Intrinsic::experimental_vector_reverse,
V->getType());
2426 return createSelReverse(
C,
X,
Y);
2430 return createSelReverse(
C,
X, FVal);
2435 return createSelReverse(
C, TVal,
Y);
2438 auto *VecTy = dyn_cast<FixedVectorType>(Sel.
getType());
2442 unsigned NumElts = VecTy->getNumElements();
2443 APInt UndefElts(NumElts, 0);
2457 cast<ShuffleVectorInst>(TVal)->isSelect()) {
2471 cast<ShuffleVectorInst>(FVal)->isSelect()) {
2492 auto *IDomNode = DT[BB]->getIDom();
2498 Value *IfTrue, *IfFalse;
2514 if (TrueSucc == FalseSucc)
2530 else if (DT.
dominates(FalseEdge, Incoming))
2535 if (
auto *
Insn = dyn_cast<Instruction>(Inputs[Pred]))
2554 if (
auto *
I = dyn_cast<Instruction>(V))
2555 CandidateBlocks.
insert(
I->getParent());
2558 if (
auto *PN = foldSelectToPhiImpl(Sel, BB, DT, Builder))
2571 Value *CondVal =
SI.getCondition();
2576 Value *
Op, *RemRes, *Remainder;
2578 bool TrueIfSigned =
false;
2592 return BinaryOperator::CreateAnd(
Op,
Add);
2604 return FoldToBitwiseAnd(Remainder);
2647 Value *CondVal =
SI.getCondition();
2651 assert(
Op->getType()->isIntOrIntVectorTy(1) &&
2652 "Op must be either i1 or vector of i1.");
2690 Value *CondVal =
SI.getCondition();
2692 bool ChangedFMF =
false;
2693 for (
bool Swap : {
false,
true}) {
2723 FastMathFlags FMF = cast<FPMathOperator>(TrueVal)->getFastMathFlags();
2724 if (FMF.
noNaNs() && !
SI.hasNoNaNs()) {
2725 SI.setHasNoNaNs(
true);
2728 if (FMF.
noInfs() && !
SI.hasNoInfs()) {
2729 SI.setHasNoInfs(
true);
2743 if (!
SI.hasNoSignedZeros() || !
SI.hasNoNaNs())
2760 Instruction *NewFNeg = UnaryOperator::CreateFNeg(Fabs);
2766 return ChangedFMF ? &
SI :
nullptr;
2784foldRoundUpIntegerWithPow2Alignment(
SelectInst &SI,
2788 Value *XBiasedHighBits =
SI.getFalseValue();
2801 const APInt *LowBitMaskCst;
2806 const APInt *BiasCst, *HighBitMaskCst;
2807 if (!
match(XBiasedHighBits,
2810 !
match(XBiasedHighBits,
2815 if (!LowBitMaskCst->
isMask())
2818 APInt InvertedLowBitMaskCst = ~*LowBitMaskCst;
2819 if (InvertedLowBitMaskCst != *HighBitMaskCst)
2822 APInt AlignmentCst = *LowBitMaskCst + 1;
2824 if (*BiasCst != AlignmentCst && *BiasCst != *LowBitMaskCst)
2828 if (*BiasCst == *LowBitMaskCst)
2829 return XBiasedHighBits;
2834 Type *Ty =
X->getType();
2836 X->getName() +
".biased");
2843struct DecomposedSelect {
2860 DecomposedSelect OuterSel;
2867 std::swap(OuterSel.TrueVal, OuterSel.FalseVal);
2875 Value *InnerSelVal = IsAndVariant ? OuterSel.FalseVal : OuterSel.TrueVal;
2879 [](
Value *V) {
return V->hasOneUse(); }))
2883 DecomposedSelect InnerSel;
2884 if (!
match(InnerSelVal,
2891 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
2893 Value *AltCond =
nullptr;
2894 auto matchOuterCond = [OuterSel, IsAndVariant, &AltCond](
auto m_InnerCond) {
2899 return IsAndVariant ?
match(OuterSel.Cond,
2909 if (matchOuterCond(
m_Specific(InnerSel.Cond))) {
2914 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
2915 InnerSel.Cond = NotInnerCond;
2920 AltCond, IsAndVariant ? OuterSel.TrueVal : InnerSel.FalseVal,
2921 IsAndVariant ? InnerSel.TrueVal : OuterSel.FalseVal);
2924 IsAndVariant ? SelInner : InnerSel.TrueVal,
2925 !IsAndVariant ? SelInner : InnerSel.FalseVal);
2929 Value *CondVal =
SI.getCondition();
2932 Type *SelType =
SI.getType();
2951 return BinaryOperator::CreateOr(CondVal, FalseVal);
2954 if (
auto *LHS = dyn_cast<FCmpInst>(CondVal))
2955 if (
auto *RHS = dyn_cast<FCmpInst>(FalseVal))
2956 if (
Value *V = foldLogicOfFCmps(LHS, RHS,
false,
2964 bool CondLogicAnd = isa<SelectInst>(CondVal);
2965 bool FalseLogicAnd = isa<SelectInst>(FalseVal);
2966 auto AndFactorization = [&](
Value *Common,
Value *InnerCond,
2972 if (FalseLogicAnd || (CondLogicAnd && Common ==
A))
2975 return BinaryOperator::CreateAnd(Common, InnerSel);
2979 return AndFactorization(
A,
B,
D);
2981 return AndFactorization(
A,
B,
C);
2983 return AndFactorization(
B,
A,
D);
2985 return AndFactorization(
B,
A,
C, CondLogicAnd && FalseLogicAnd);
2992 return BinaryOperator::CreateAnd(CondVal, TrueVal);
2995 if (
auto *LHS = dyn_cast<FCmpInst>(CondVal))
2996 if (
auto *RHS = dyn_cast<FCmpInst>(TrueVal))
2997 if (
Value *V = foldLogicOfFCmps(LHS, RHS,
true,
3005 bool CondLogicOr = isa<SelectInst>(CondVal);
3006 bool TrueLogicOr = isa<SelectInst>(TrueVal);
3007 auto OrFactorization = [&](
Value *Common,
Value *InnerCond,
3013 if (TrueLogicOr || (CondLogicOr && Common ==
A))
3016 return BinaryOperator::CreateOr(Common, InnerSel);
3020 return OrFactorization(
A,
B,
D);
3022 return OrFactorization(
A,
B,
C);
3024 return OrFactorization(
B,
A,
D);
3026 return OrFactorization(
B,
A,
C, CondLogicOr && TrueLogicOr);
3069 return BinaryOperator::CreateXor(
A,
B);
3103 auto *FI =
new FreezeInst(*
Y, (*Y)->getName() +
".fr");
3109 if (
auto *Op1SI = dyn_cast<SelectInst>(Op1))
3110 if (
auto *
I = foldAndOrOfSelectUsingImpliedCond(CondVal, *Op1SI,
3114 if (
auto *ICmp0 = dyn_cast<ICmpInst>(CondVal))
3115 if (
auto *ICmp1 = dyn_cast<ICmpInst>(Op1))
3116 if (
auto *V = foldAndOrOfICmps(ICmp0, ICmp1, SI, IsAnd,
3127 if (Res && *Res ==
false)
3133 if (Res && *Res ==
false)
3142 if (Res && *Res ==
true)
3148 if (Res && *Res ==
true)
3161 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3162 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3163 bool MayNeedFreeze = SelCond && SelFVal &&
3164 match(SelFVal->getTrueValue(),
3177 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3178 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3179 bool MayNeedFreeze = SelCond && SelFVal &&
3180 match(SelCond->getTrueValue(),
3222 auto MatchForward = [&](
Value *CommonAncestor) {
3223 const APInt *
C =
nullptr;
3224 if (CtlzOp == CommonAncestor)
3241 const APInt *
C =
nullptr;
3242 Value *CommonAncestor;
3243 if (MatchForward(Cond0)) {
3247 if (!MatchForward(CommonAncestor))
3284 Type *SelType =
SI.getType();
3291 Value *Cond0, *Ctlz, *CtlzOp;
3305 !isSafeToRemoveBitCeilSelect(Pred, Cond0, Cond1, CtlzOp,
BitWidth))
3334 FastMathFlags FMF = cast<FPMathOperator>(TrueVal)->getFastMathFlags();
3345 Value *CondVal =
SI.getCondition();
3348 Type *SelType =
SI.getType();
3357 if (
Instruction *
I = canonicalizeScalarSelectOfVecs(SI, *
this))
3393 return new ZExtInst(CondVal, SelType);
3397 return new SExtInst(CondVal, SelType);
3402 return new ZExtInst(NotCond, SelType);
3408 return new SExtInst(NotCond, SelType);
3412 auto *SIFPOp = dyn_cast<FPMathOperator>(&SI);
3414 if (
auto *FCmp = dyn_cast<FCmpInst>(CondVal)) {
3416 Value *Cmp0 = FCmp->getOperand(0), *Cmp1 = FCmp->getOperand(1);
3418 if ((Cmp0 == TrueVal && Cmp1 == FalseVal) ||
3419 (Cmp0 == FalseVal && Cmp1 == TrueVal)) {
3431 FCmp->getName() +
".inv");
3451 Value *MatchCmp0 =
nullptr;
3452 Value *MatchCmp1 =
nullptr;
3464 if (Cmp0 == MatchCmp0 &&
3465 matchFMulByZeroIfResultEqZero(*
this, Cmp0, Cmp1, MatchCmp1, MatchCmp0,
3466 SI, SIFPOp->hasNoSignedZeros()))
3476 if (SIFPOp->hasNoNaNs() && SIFPOp->hasNoSignedZeros()) {
3489 if (
Instruction *Fabs = foldSelectWithFCmpToFabs(SI, *
this))
3493 if (
ICmpInst *ICI = dyn_cast<ICmpInst>(CondVal))
3507 auto *TI = dyn_cast<Instruction>(TrueVal);
3508 auto *FI = dyn_cast<Instruction>(FalseVal);
3509 if (TI && FI && TI->getOpcode() == FI->
getOpcode())
3528 if (isa<VectorType>(CondVal->
getType()) && !isa<VectorType>(
Idx->getType()))
3541 if (
auto *TrueGep = dyn_cast<GetElementPtrInst>(TrueVal))
3542 if (
auto *NewGep = SelectGepWithBase(TrueGep, FalseVal,
false))
3544 if (
auto *FalseGep = dyn_cast<GetElementPtrInst>(FalseVal))
3545 if (
auto *NewGep = SelectGepWithBase(FalseGep, TrueVal,
true))
3561 RHS2, SI, SPF, RHS))
3565 RHS2, SI, SPF, LHS))
3574 bool IsCastNeeded =
LHS->
getType() != SelType;
3575 Value *CmpLHS = cast<CmpInst>(CondVal)->getOperand(0);
3576 Value *CmpRHS = cast<CmpInst>(CondVal)->getOperand(1);
3579 ((CmpLHS != LHS && CmpLHS != RHS) ||
3580 (CmpRHS != LHS && CmpRHS != RHS)))) {
3589 cast<FPMathOperator>(
SI.getCondition())->getFastMathFlags();
3605 if (
auto *PN = dyn_cast<PHINode>(
SI.getCondition()))
3607 if (canSelectOperandBeMappingIntoPredBlock(TrueVal, SI) &&
3608 canSelectOperandBeMappingIntoPredBlock(FalseVal, SI))
3612 if (
SelectInst *TrueSI = dyn_cast<SelectInst>(TrueVal)) {
3613 if (TrueSI->getCondition()->getType() == CondVal->
getType()) {
3615 if (TrueSI->getCondition() == CondVal) {
3616 if (
SI.getTrueValue() == TrueSI->getTrueValue())
3624 if (TrueSI->getFalseValue() == FalseVal && TrueSI->hasOneUse()) {
3632 if (
SelectInst *FalseSI = dyn_cast<SelectInst>(FalseVal)) {
3633 if (FalseSI->getCondition()->getType() == CondVal->
getType()) {
3635 if (FalseSI->getCondition() == CondVal) {
3636 if (
SI.getFalseValue() == FalseSI->getFalseValue())
3641 if (FalseSI->getTrueValue() == TrueVal && FalseSI->hasOneUse()) {
3658 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(0))) {
3659 if (TrueBOSI->getCondition() == CondVal) {
3665 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(1))) {
3666 if (TrueBOSI->getCondition() == CondVal) {
3677 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(0))) {
3678 if (FalseBOSI->getCondition() == CondVal) {
3684 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(1))) {
3685 if (FalseBOSI->getCondition() == CondVal) {
3698 SI.swapProfMetadata();
3713 if (Known.One.isOne())
3715 if (Known.Zero.isOne())
3723 if (
Value *V = foldSelectCmpXchg(SI))
3741 if (
Value *V = foldRoundUpIntegerWithPow2Alignment(SI,
Builder))
3751 auto *MaskedInst = cast<IntrinsicInst>(TrueVal);
3752 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
3753 MaskedInst->setArgOperand(3, FalseVal );
3768 bool CanMergeSelectIntoLoad =
false;
3772 if (CanMergeSelectIntoLoad) {
3773 auto *MaskedInst = cast<IntrinsicInst>(FalseVal);
3774 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
3775 MaskedInst->setArgOperand(3, TrueVal );
SmallVector< AArch64_IMM::ImmInsnModel, 4 > Insn
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
This file provides internal interfaces used to implement the InstCombine.
static Value * canonicalizeSaturatedAdd(ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
static Instruction * foldSetClearBits(SelectInst &Sel, InstCombiner::BuilderTy &Builder)
Canonicalize a set or clear of a masked set of constant bits to select-of-constants form.
static Instruction * foldSelectICmpAndAnd(Type *SelType, const ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
We want to turn: (select (icmp eq (and X, Y), 0), (and (lshr X, Z), 1), 1) into: zext (icmp ne i32 (a...
static unsigned getSelectFoldableOperands(BinaryOperator *I)
We want to turn code that looks like this: C = or A, B D = select cond, C, A into: C = select cond,...
static Instruction * foldSelectZeroOrMul(SelectInst &SI, InstCombinerImpl &IC)
static Value * canonicalizeSaturatedSubtract(const ICmpInst *ICI, const Value *TrueVal, const Value *FalseVal, InstCombiner::BuilderTy &Builder)
Transform patterns such as (a > b) ? a - b : 0 into usub.sat(a, b).
static Value * foldAbsDiff(ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
Try to match patterns with select and subtract as absolute difference.
static Instruction * foldSelectBinOpIdentity(SelectInst &Sel, const TargetLibraryInfo &TLI, InstCombinerImpl &IC)
Replace a select operand based on an equality comparison with the identity constant of a binop.
static Value * foldSelectICmpAndZeroShl(const ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
We want to turn: (select (icmp eq (and X, C1), 0), 0, (shl [nsw/nuw] X, C2)); iff C1 is a mask and th...
static Value * foldSelectICmpAndBinOp(const ICmpInst *IC, Value *TrueVal, Value *FalseVal, InstCombiner::BuilderTy &Builder)
We want to turn: (select (icmp eq (and X, C1), 0), Y, (BinOp Y, C2)) into: IF C2 u>= C1 (BinOp Y,...
static Value * foldSelectICmpLshrAshr(const ICmpInst *IC, Value *TrueVal, Value *FalseVal, InstCombiner::BuilderTy &Builder)
We want to turn: (select (icmp sgt x, C), lshr (X, Y), ashr (X, Y)); iff C s>= -1 (select (icmp slt x...
static bool isSelect01(const APInt &C1I, const APInt &C2I)
static Value * foldSelectICmpAnd(SelectInst &Sel, ICmpInst *Cmp, InstCombiner::BuilderTy &Builder)
This folds: select (icmp eq (and X, C1)), TC, FC iff C1 is a power 2 and the difference between TC an...
This file provides the interface for the instcombine pass implementation.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static const uint32_t IV[8]
bool bitwiseIsEqual(const APFloat &RHS) const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
bool isMinSignedValue() const
Determine if this is the smallest signed value.
uint64_t getZExtValue() const
Get zero extended value.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
unsigned getBitWidth() const
Return the number of bits in the APInt.
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
bool isMinValue() const
Determine if this is the smallest unsigned value.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
unsigned countLeadingZeros() const
unsigned logBase2() const
bool isMask(unsigned numBits) const
bool isMaxSignedValue() const
Determine if this is the largest signed value.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
bool isOne() const
Determine if this is a value of 1.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
bool isMaxValue() const
Determine if this is the largest unsigned value.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
MutableArrayRef< ResultElem > assumptions()
Access the list of assumption handles currently tracked for this function.
An instruction that atomically checks whether a specified value is in a memory location,...
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
static BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=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)
This class represents a function call, abstracting a target machine's calling convention.
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.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ ICMP_ULT
unsigned less than
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
bool isFPPredicate() const
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Predicate getPredicate() const
Return the predicate for this instruction.
static bool isUnordered(Predicate predicate)
Determine if the predicate is an unordered operation.
Predicate getFlippedStrictnessPredicate() const
For predicate of kind "is X or equal to 0" returns the predicate "is X".
bool isIntPredicate() const
static Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * 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 * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)
Return the identity constant for a binary opcode.
static Constant * getNeg(Constant *C, bool 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.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Utility class for floating point operations which can have information about relaxed accuracy require...
FastMathFlags getFastMathFlags() const
Convenience function for getting all the fast-math flags.
Convenience struct for specifying and reasoning about fast-math flags.
bool noSignedZeros() const
void setNoSignedZeros(bool B=true)
This class represents a freeze function that returns random concrete value if an operand is either a ...
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
bool isInBounds() const
Determine whether the GEP has the inbounds flag.
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)
uint64_t getType(const MachineInstr &MI) const
This instruction compares its operands according to the predicate given to the constructor.
bool isEquality() const
Return true if this predicate is either EQ or NE.
static bool isEquality(Predicate P)
Return true if this predicate is either EQ or NE.
Common base class shared among various IRBuilders.
CallInst * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with 1 operand which is mangled on its type.
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")
Return a vector value that contains.
ConstantInt * getTrue()
Get the constant value for i1 true.
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
Value * CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Value * CreateFreeze(Value *V, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
void setFastMathFlags(FastMathFlags NewFMF)
Set the fast-math flags to be used with generated fp-math operators.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateIsNeg(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg < 0.
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
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 * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateLogicalAnd(Value *Cond1, Value *Cond2, const Twine &Name="")
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="")
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateLogicalOr(Value *Cond1, Value *Cond2, const Twine &Name="")
Value * CreateFNeg(Value *V, const Twine &Name="", MDNode *FPMathTag=nullptr)
bool fmulByZeroIsZero(Value *MulVal, FastMathFlags FMF, const Instruction *CtxI) const
Check if fmul MulVal, +0.0 will yield +0.0 (or signed zero is ignorable).
KnownFPClass computeKnownFPClass(Value *Val, FastMathFlags FMF, FPClassTest Interested=fcAllFlags, const Instruction *CtxI=nullptr, unsigned Depth=0) const
Instruction * foldOpIntoPhi(Instruction &I, PHINode *PN)
Given a binary operator, cast instruction, or select which has a PHI node as operand #0,...
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)
Constant * getLosslessTrunc(Constant *C, Type *TruncTy, unsigned ExtOp)
Instruction * foldSelectIntoOp(SelectInst &SI, Value *, Value *)
Try to fold the select into one of the operands to allow further optimization.
Instruction * visitSelectInst(SelectInst &SI)
Instruction * foldSelectOfBools(SelectInst &SI)
Instruction * foldSelectExtConst(SelectInst &Sel)
const DataLayout & getDataLayout() const
static bool isCanonicalPredicate(CmpInst::Predicate Pred)
Predicate canonicalization reduces the number of patterns that need to be matched by other transforms...
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, unsigned Depth=0, const Instruction *CxtI=nullptr)
Instruction * InsertNewInstBefore(Instruction *New, BasicBlock::iterator Old)
Inserts an instruction New before instruction Old.
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
static bool shouldAvoidAbsorbingNotIntoSelect(const SelectInst &SI)
static std::optional< std::pair< CmpInst::Predicate, Constant * > > getFlippedStrictnessPredicateAndConstant(CmpInst::Predicate Pred, Constant *C)
void replaceUse(Use &U, Value *NewValue)
Replace use and add the previously used value to the worklist.
InstructionWorklist & Worklist
A worklist of the instructions that need to be simplified.
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
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
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
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.