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) {
212 V =
Builder.CreateZExtOrTrunc(V, SelType);
213 V =
Builder.CreateShl(V, ValZeros - AndZeros);
214 }
else if (ValZeros < AndZeros) {
215 V =
Builder.CreateLShr(V, AndZeros - ValZeros);
216 V =
Builder.CreateZExtOrTrunc(V, SelType);
218 V =
Builder.CreateZExtOrTrunc(V, SelType);
223 bool ShouldNotVal = !TC.
isZero();
224 ShouldNotVal ^= Pred == ICmpInst::ICMP_NE;
226 V =
Builder.CreateXor(V, ValC);
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() &&
606 Value *MaskB = HasShift ?
Builder.CreateShl(One, Z) : One;
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) >
786 V =
Builder.CreateZExtOrTrunc(V,
Y->getType());
787 V =
Builder.CreateShl(V, C2Log - C1Log);
788 }
else if (C1Log > C2Log) {
789 V =
Builder.CreateLShr(V, C1Log - C2Log);
790 V =
Builder.CreateZExtOrTrunc(V,
Y->getType());
792 V =
Builder.CreateZExtOrTrunc(V,
Y->getType());
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,
909 return Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat,
A,
924 "Unexpected isUnsigned predicate!");
930 bool IsNegative =
false;
943 if (IsNegative && !TrueVal->hasOneUse() && !ICI->
hasOneUse())
948 Value *Result =
Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat,
A,
B);
950 Result =
Builder.CreateNeg(Result);
956 if (!Cmp->hasOneUse())
960 Value *Cmp0 = Cmp->getOperand(0);
961 Value *Cmp1 = Cmp->getOperand(1);
969 return Builder.CreateBinaryIntrinsic(
998 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat,
X,
Y);
1008 return Builder.CreateBinaryIntrinsic(
1018 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp1,
Y);
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());
1059 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, TI,
Builder.getTrue());
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 Value *ShouldReplaceLow =
Builder.CreateICmpSLT(
X, ThresholdLowIncl);
1504 Value *ShouldReplaceHigh =
Builder.CreateICmpSGE(
X, ThresholdHighExcl);
1505 Value *MaybeReplacedLow =
1506 Builder.CreateSelect(ShouldReplaceLow, ReplacementLow,
X);
1511 ShouldReplaceHigh, ReplacementHigh, MaybeReplacedLow);
1555 Value *SelVal0, *SelVal1;
1564 auto MatchesSelectValue = [SelVal0, SelVal1](
Constant *
C) {
1565 return C->isElementWiseEqual(SelVal0) ||
C->isElementWiseEqual(SelVal1);
1569 if (MatchesSelectValue(C0))
1573 auto FlippedStrictness =
1575 if (!FlippedStrictness)
1579 if (!MatchesSelectValue(FlippedStrictness->second))
1588 Cmp.getName() +
".inv");
1599 if (!
Cmp->hasOneUse())
1629 Value *TVal =
SI.getTrueValue();
1630 Value *FVal =
SI.getFalseValue();
1634 return Builder.CreateBinaryIntrinsic(Intrinsic::umax, V, TVal);
1637 return Builder.CreateBinaryIntrinsic(Intrinsic::umin, V, TVal);
1640 return Builder.CreateBinaryIntrinsic(Intrinsic::smax, V, TVal);
1643 return Builder.CreateBinaryIntrinsic(Intrinsic::smin, V, TVal);
1656 const APInt *BinOpC;
1675 if (
Instruction *NewSPF = canonicalizeSPF(SI, *ICI, *
this))
1678 if (
Value *V = foldSelectInstWithICmpConst(SI, ICI,
Builder))
1681 if (
Value *V = canonicalizeClampLike(SI, *ICI,
Builder))
1685 tryToReuseConstantFromSelectInComparison(SI, *ICI, *
this))
1692 bool Changed =
false;
1698 if (CmpRHS != CmpLHS && isa<Constant>(CmpRHS) && !isa<Constant>(CmpLHS)) {
1701 SI.setOperand(1, CmpRHS);
1705 SI.setOperand(2, CmpRHS);
1722 SI.swapProfMetadata();
1728 if (
TrueVal->getType()->isIntOrIntVectorTy()) {
1735 bool IsBitTest =
false;
1743 Y = &MinSignedValue;
1745 TrueWhenUnset =
false;
1748 Y = &MinSignedValue;
1750 TrueWhenUnset =
true;
1755 if (TrueWhenUnset && TrueVal ==
X &&
1759 else if (!TrueWhenUnset && FalseVal ==
X &&
1763 else if (TrueWhenUnset && FalseVal ==
X &&
1767 else if (!TrueWhenUnset && TrueVal ==
X &&
1795 if (
Value *V = foldSelectCttzCtlz(ICI, TrueVal, FalseVal,
Builder))
1807 return Changed ? &
SI :
nullptr;
1819static bool canSelectOperandBeMappingIntoPredBlock(
const Value *V,
1824 if (!
I)
return true;
1828 const PHINode *CondPHI = cast<PHINode>(
SI.getCondition());
1830 if (
const PHINode *VP = dyn_cast<PHINode>(
I))
1831 if (VP->getParent() == CondPHI->
getParent())
1855 if (
C ==
A ||
C ==
B) {
1870 Value *CondVal =
SI.getCondition();
1873 auto *TI = dyn_cast<Instruction>(TrueVal);
1874 auto *FI = dyn_cast<Instruction>(FalseVal);
1875 if (!TI || !FI || !TI->hasOneUse() || !FI->hasOneUse())
1879 if ((TI->getOpcode() == Instruction::Sub &&
1880 FI->getOpcode() == Instruction::Add) ||
1881 (TI->getOpcode() == Instruction::FSub &&
1882 FI->getOpcode() == Instruction::FAdd)) {
1885 }
else if ((FI->getOpcode() == Instruction::Sub &&
1886 TI->getOpcode() == Instruction::Add) ||
1887 (FI->getOpcode() == Instruction::FSub &&
1888 TI->getOpcode() == Instruction::FAdd)) {
1894 Value *OtherAddOp =
nullptr;
1895 if (SubOp->getOperand(0) == AddOp->
getOperand(0)) {
1897 }
else if (SubOp->getOperand(0) == AddOp->
getOperand(1)) {
1905 if (
SI.getType()->isFPOrFPVectorTy()) {
1906 NegVal =
Builder.CreateFNeg(SubOp->getOperand(1));
1907 if (
Instruction *NegInst = dyn_cast<Instruction>(NegVal)) {
1909 Flags &= SubOp->getFastMathFlags();
1910 NegInst->setFastMathFlags(Flags);
1913 NegVal =
Builder.CreateNeg(SubOp->getOperand(1));
1916 Value *NewTrueOp = OtherAddOp;
1917 Value *NewFalseOp = NegVal;
1920 Value *NewSel =
Builder.CreateSelect(CondVal, NewTrueOp, NewFalseOp,
1921 SI.getName() +
".p", &SI);
1923 if (
SI.getType()->isFPOrFPVectorTy()) {
1925 BinaryOperator::CreateFAdd(SubOp->getOperand(0), NewSel);
1928 Flags &= SubOp->getFastMathFlags();
1932 return BinaryOperator::CreateAdd(SubOp->getOperand(0), NewSel);
1945 Value *CondVal =
SI.getCondition();
1957 auto IsSignedSaturateLimit = [&](
Value *Limit,
bool IsAdd) {
1967 auto IsZeroOrOne = [](
const APInt &
C) {
return C.isZero() ||
C.isOne(); };
1984 IsMinMax(TrueVal, FalseVal))
1991 IsMinMax(FalseVal, TrueVal))
1997 IsMinMax(TrueVal, FalseVal))
2002 IsMinMax(FalseVal, TrueVal))
2007 IsMinMax(FalseVal, TrueVal))
2012 IsMinMax(TrueVal, FalseVal))
2023 NewIntrinsicID = Intrinsic::uadd_sat;
2024 else if (II->
getIntrinsicID() == Intrinsic::usub_with_overflow &&
2027 NewIntrinsicID = Intrinsic::usub_sat;
2028 else if (II->
getIntrinsicID() == Intrinsic::sadd_with_overflow &&
2029 IsSignedSaturateLimit(TrueVal,
true))
2038 NewIntrinsicID = Intrinsic::sadd_sat;
2039 else if (II->
getIntrinsicID() == Intrinsic::ssub_with_overflow &&
2040 IsSignedSaturateLimit(TrueVal,
false))
2049 NewIntrinsicID = Intrinsic::ssub_sat;
2070 if (ExtOpcode != Instruction::ZExt && ExtOpcode != Instruction::SExt)
2076 Type *SmallType =
X->getType();
2078 auto *
Cmp = dyn_cast<CmpInst>(
Cond);
2080 (!Cmp ||
Cmp->getOperand(0)->getType() != SmallType))
2089 Value *TruncCVal = cast<Value>(TruncC);
2122 Value *CondVal =
SI.getCondition();
2124 auto *CondValTy = dyn_cast<FixedVectorType>(CondVal->
getType());
2128 unsigned NumElts = CondValTy->getNumElements();
2130 Mask.reserve(NumElts);
2131 for (
unsigned i = 0; i != NumElts; ++i) {
2141 Mask.push_back(i + NumElts);
2142 }
else if (isa<UndefValue>(Elt)) {
2162 auto *Ty = dyn_cast<VectorType>(Sel.
getType());
2194 if (TVal ==
A || TVal ==
B || FVal ==
A || FVal ==
B)
2211 if (TSrc ==
C && FSrc ==
D) {
2215 }
else if (TSrc ==
D && FSrc ==
C) {
2254 auto *Extract = dyn_cast<ExtractValueInst>(V);
2257 if (Extract->getIndices()[0] !=
I)
2259 return dyn_cast<AtomicCmpXchgInst>(Extract->getAggregateOperand());
2265 if (
auto *
Select = dyn_cast<SelectInst>(
SI.user_back()))
2266 if (
Select->getCondition() ==
SI.getCondition())
2267 if (
Select->getFalseValue() ==
SI.getTrueValue() ||
2268 Select->getTrueValue() ==
SI.getFalseValue())
2272 auto *CmpXchg = isExtractFromCmpXchg(
SI.getCondition(), 1);
2279 if (
auto *
X = isExtractFromCmpXchg(
SI.getTrueValue(), 0))
2280 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getFalseValue())
2281 return SI.getFalseValue();
2286 if (
auto *
X = isExtractFromCmpXchg(
SI.getFalseValue(), 0))
2287 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getTrueValue())
2288 return SI.getFalseValue();
2312 Value *SV0, *SV1, *SA0, *SA1;
2321 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2327 Or1->
getOpcode() == BinaryOperator::LShr &&
2328 "Illegal or(shift,shift) pair");
2343 bool IsFshl = (ShAmt == SA0);
2345 if ((IsFshl && TVal != SV0) || (!IsFshl && TVal != SV1))
2359 SV1 =
Builder.CreateFreeze(SV1);
2361 SV0 =
Builder.CreateFreeze(SV0);
2366 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
2387 assert(TC != FC &&
"Expected equal select arms to simplify");
2391 bool IsTrueIfSignSet;
2395 X->getType() != SelType)
2416 if (!isa<VectorType>(Sel.
getType()))
2427 if (
auto *
I = dyn_cast<Instruction>(V))
2428 I->copyIRFlags(&Sel);
2431 M, Intrinsic::experimental_vector_reverse,
V->getType());
2439 return createSelReverse(
C,
X,
Y);
2443 return createSelReverse(
C,
X, FVal);
2448 return createSelReverse(
C, TVal,
Y);
2451 auto *VecTy = dyn_cast<FixedVectorType>(Sel.
getType());
2455 unsigned NumElts = VecTy->getNumElements();
2456 APInt UndefElts(NumElts, 0);
2470 cast<ShuffleVectorInst>(TVal)->isSelect()) {
2484 cast<ShuffleVectorInst>(FVal)->isSelect()) {
2505 auto *IDomNode = DT[BB]->getIDom();
2511 Value *IfTrue, *IfFalse;
2527 if (TrueSucc == FalseSucc)
2543 else if (DT.
dominates(FalseEdge, Incoming))
2548 if (
auto *
Insn = dyn_cast<Instruction>(Inputs[Pred]))
2556 PN->addIncoming(Inputs[Pred], Pred);
2567 if (
auto *
I = dyn_cast<Instruction>(V))
2568 CandidateBlocks.
insert(
I->getParent());
2571 if (
auto *PN = foldSelectToPhiImpl(Sel, BB, DT, Builder))
2584 Value *CondVal =
SI.getCondition();
2589 Value *
Op, *RemRes, *Remainder;
2591 bool TrueIfSigned =
false;
2605 return BinaryOperator::CreateAnd(
Op,
Add);
2617 return FoldToBitwiseAnd(Remainder);
2660 Value *CondVal =
SI.getCondition();
2664 assert(
Op->getType()->isIntOrIntVectorTy(1) &&
2665 "Op must be either i1 or vector of i1.");
2703 Value *CondVal =
SI.getCondition();
2705 bool ChangedFMF =
false;
2706 for (
bool Swap : {
false,
true}) {
2736 FastMathFlags FMF = cast<FPMathOperator>(TrueVal)->getFastMathFlags();
2737 if (FMF.
noNaNs() && !
SI.hasNoNaNs()) {
2738 SI.setHasNoNaNs(
true);
2741 if (FMF.
noInfs() && !
SI.hasNoInfs()) {
2742 SI.setHasNoInfs(
true);
2756 if (!
SI.hasNoSignedZeros() || !
SI.hasNoNaNs())
2773 Instruction *NewFNeg = UnaryOperator::CreateFNeg(Fabs);
2779 return ChangedFMF ? &
SI :
nullptr;
2797foldRoundUpIntegerWithPow2Alignment(
SelectInst &SI,
2801 Value *XBiasedHighBits =
SI.getFalseValue();
2814 const APInt *LowBitMaskCst;
2819 const APInt *BiasCst, *HighBitMaskCst;
2820 if (!
match(XBiasedHighBits,
2823 !
match(XBiasedHighBits,
2828 if (!LowBitMaskCst->
isMask())
2831 APInt InvertedLowBitMaskCst = ~*LowBitMaskCst;
2832 if (InvertedLowBitMaskCst != *HighBitMaskCst)
2835 APInt AlignmentCst = *LowBitMaskCst + 1;
2837 if (*BiasCst != AlignmentCst && *BiasCst != *LowBitMaskCst)
2841 if (*BiasCst == *LowBitMaskCst)
2842 return XBiasedHighBits;
2847 Type *Ty =
X->getType();
2849 X->getName() +
".biased");
2856struct DecomposedSelect {
2873 DecomposedSelect OuterSel;
2880 std::swap(OuterSel.TrueVal, OuterSel.FalseVal);
2888 Value *InnerSelVal = IsAndVariant ? OuterSel.FalseVal : OuterSel.TrueVal;
2892 [](
Value *V) {
return V->hasOneUse(); }))
2896 DecomposedSelect InnerSel;
2897 if (!
match(InnerSelVal,
2904 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
2906 Value *AltCond =
nullptr;
2907 auto matchOuterCond = [OuterSel, &AltCond](
auto m_InnerCond) {
2915 if (matchOuterCond(
m_Specific(InnerSel.Cond))) {
2920 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
2921 InnerSel.Cond = NotInnerCond;
2926 AltCond, IsAndVariant ? OuterSel.TrueVal : InnerSel.FalseVal,
2927 IsAndVariant ? InnerSel.TrueVal : OuterSel.FalseVal);
2930 IsAndVariant ? SelInner : InnerSel.TrueVal,
2931 !IsAndVariant ? SelInner : InnerSel.FalseVal);
2935 Value *CondVal =
SI.getCondition();
2938 Type *SelType =
SI.getType();
2957 return BinaryOperator::CreateOr(CondVal, FalseVal);
2960 if (
auto *LHS = dyn_cast<FCmpInst>(CondVal))
2961 if (
auto *RHS = dyn_cast<FCmpInst>(FalseVal))
2962 if (
Value *V = foldLogicOfFCmps(LHS, RHS,
false,
2970 bool CondLogicAnd = isa<SelectInst>(CondVal);
2971 bool FalseLogicAnd = isa<SelectInst>(FalseVal);
2972 auto AndFactorization = [&](
Value *Common,
Value *InnerCond,
2978 if (FalseLogicAnd || (CondLogicAnd && Common ==
A))
2981 return BinaryOperator::CreateAnd(Common, InnerSel);
2985 return AndFactorization(
A,
B,
D);
2987 return AndFactorization(
A,
B,
C);
2989 return AndFactorization(
B,
A,
D);
2991 return AndFactorization(
B,
A,
C, CondLogicAnd && FalseLogicAnd);
2998 return BinaryOperator::CreateAnd(CondVal, TrueVal);
3001 if (
auto *LHS = dyn_cast<FCmpInst>(CondVal))
3002 if (
auto *RHS = dyn_cast<FCmpInst>(TrueVal))
3003 if (
Value *V = foldLogicOfFCmps(LHS, RHS,
true,
3011 bool CondLogicOr = isa<SelectInst>(CondVal);
3012 bool TrueLogicOr = isa<SelectInst>(TrueVal);
3013 auto OrFactorization = [&](
Value *Common,
Value *InnerCond,
3019 if (TrueLogicOr || (CondLogicOr && Common ==
A))
3022 return BinaryOperator::CreateOr(Common, InnerSel);
3026 return OrFactorization(
A,
B,
D);
3028 return OrFactorization(
A,
B,
C);
3030 return OrFactorization(
B,
A,
D);
3032 return OrFactorization(
B,
A,
C, CondLogicOr && TrueLogicOr);
3083 return BinaryOperator::CreateXor(
A,
B);
3117 auto *FI =
new FreezeInst(*
Y, (*Y)->getName() +
".fr");
3123 if (
auto *Op1SI = dyn_cast<SelectInst>(Op1))
3124 if (
auto *
I = foldAndOrOfSelectUsingImpliedCond(CondVal, *Op1SI,
3128 if (
auto *ICmp0 = dyn_cast<ICmpInst>(CondVal))
3129 if (
auto *ICmp1 = dyn_cast<ICmpInst>(Op1))
3130 if (
auto *V = foldAndOrOfICmps(ICmp0, ICmp1, SI, IsAnd,
3141 if (Res && *Res ==
false)
3147 if (Res && *Res ==
false)
3156 if (Res && *Res ==
true)
3162 if (Res && *Res ==
true)
3175 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3176 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3177 bool MayNeedFreeze = SelCond && SelFVal &&
3178 match(SelFVal->getTrueValue(),
3191 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3192 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3193 bool MayNeedFreeze = SelCond && SelFVal &&
3194 match(SelCond->getTrueValue(),
3236 auto MatchForward = [&](
Value *CommonAncestor) {
3237 const APInt *
C =
nullptr;
3238 if (CtlzOp == CommonAncestor)
3255 const APInt *
C =
nullptr;
3256 Value *CommonAncestor;
3257 if (MatchForward(Cond0)) {
3261 if (!MatchForward(CommonAncestor))
3298 Type *SelType =
SI.getType();
3305 Value *Cond0, *Ctlz, *CtlzOp;
3319 !isSafeToRemoveBitCeilSelect(Pred, Cond0, Cond1, CtlzOp,
BitWidth))
3348 FastMathFlags FMF = cast<FPMathOperator>(TrueVal)->getFastMathFlags();
3359 Value *CondVal =
SI.getCondition();
3362 Type *SelType =
SI.getType();
3371 if (
Instruction *
I = canonicalizeScalarSelectOfVecs(SI, *
this))
3429 return new ZExtInst(CondVal, SelType);
3433 return new SExtInst(CondVal, SelType);
3438 return new ZExtInst(NotCond, SelType);
3444 return new SExtInst(NotCond, SelType);
3448 auto *SIFPOp = dyn_cast<FPMathOperator>(&SI);
3450 if (
auto *FCmp = dyn_cast<FCmpInst>(CondVal)) {
3452 Value *Cmp0 = FCmp->getOperand(0), *Cmp1 = FCmp->getOperand(1);
3454 if ((Cmp0 == TrueVal && Cmp1 == FalseVal) ||
3455 (Cmp0 == FalseVal && Cmp1 == TrueVal)) {
3467 FCmp->getName() +
".inv");
3487 Value *MatchCmp0 =
nullptr;
3488 Value *MatchCmp1 =
nullptr;
3500 if (Cmp0 == MatchCmp0 &&
3501 matchFMulByZeroIfResultEqZero(*
this, Cmp0, Cmp1, MatchCmp1, MatchCmp0,
3502 SI, SIFPOp->hasNoSignedZeros()))
3512 if (SIFPOp->hasNoNaNs() && SIFPOp->hasNoSignedZeros()) {
3525 if (
Instruction *Fabs = foldSelectWithFCmpToFabs(SI, *
this))
3529 if (
ICmpInst *ICI = dyn_cast<ICmpInst>(CondVal))
3543 auto *TI = dyn_cast<Instruction>(TrueVal);
3544 auto *FI = dyn_cast<Instruction>(FalseVal);
3545 if (TI && FI && TI->getOpcode() == FI->
getOpcode())
3564 if (isa<VectorType>(CondVal->
getType()) && !isa<VectorType>(
Idx->getType()))
3577 if (
auto *TrueGep = dyn_cast<GetElementPtrInst>(TrueVal))
3578 if (
auto *NewGep = SelectGepWithBase(TrueGep, FalseVal,
false))
3580 if (
auto *FalseGep = dyn_cast<GetElementPtrInst>(FalseVal))
3581 if (
auto *NewGep = SelectGepWithBase(FalseGep, TrueVal,
true))
3597 RHS2, SI, SPF, RHS))
3601 RHS2, SI, SPF, LHS))
3610 bool IsCastNeeded =
LHS->
getType() != SelType;
3611 Value *CmpLHS = cast<CmpInst>(CondVal)->getOperand(0);
3612 Value *CmpRHS = cast<CmpInst>(CondVal)->getOperand(1);
3615 ((CmpLHS != LHS && CmpLHS != RHS) ||
3616 (CmpRHS != LHS && CmpRHS != RHS)))) {
3625 cast<FPMathOperator>(
SI.getCondition())->getFastMathFlags();
3641 if (
auto *PN = dyn_cast<PHINode>(
SI.getCondition()))
3643 if (canSelectOperandBeMappingIntoPredBlock(TrueVal, SI) &&
3644 canSelectOperandBeMappingIntoPredBlock(FalseVal, SI))
3648 if (
SelectInst *TrueSI = dyn_cast<SelectInst>(TrueVal)) {
3649 if (TrueSI->getCondition()->getType() == CondVal->
getType()) {
3651 if (TrueSI->getCondition() == CondVal) {
3652 if (
SI.getTrueValue() == TrueSI->getTrueValue())
3660 if (TrueSI->getFalseValue() == FalseVal && TrueSI->hasOneUse()) {
3668 if (
SelectInst *FalseSI = dyn_cast<SelectInst>(FalseVal)) {
3669 if (FalseSI->getCondition()->getType() == CondVal->
getType()) {
3671 if (FalseSI->getCondition() == CondVal) {
3672 if (
SI.getFalseValue() == FalseSI->getFalseValue())
3677 if (FalseSI->getTrueValue() == TrueVal && FalseSI->hasOneUse()) {
3694 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(0))) {
3695 if (TrueBOSI->getCondition() == CondVal) {
3701 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(1))) {
3702 if (TrueBOSI->getCondition() == CondVal) {
3713 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(0))) {
3714 if (FalseBOSI->getCondition() == CondVal) {
3720 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(1))) {
3721 if (FalseBOSI->getCondition() == CondVal) {
3734 SI.swapProfMetadata();
3749 if (Known.One.isOne())
3751 if (Known.Zero.isOne())
3759 if (
Value *V = foldSelectCmpXchg(SI))
3777 if (
Value *V = foldRoundUpIntegerWithPow2Alignment(SI,
Builder))
3787 auto *MaskedInst = cast<IntrinsicInst>(TrueVal);
3788 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
3789 MaskedInst->setArgOperand(3, FalseVal );
3804 bool CanMergeSelectIntoLoad =
false;
3808 if (CanMergeSelectIntoLoad) {
3809 auto *MaskedInst = cast<IntrinsicInst>(FalseVal);
3810 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
3811 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...
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 * 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.
This class represents an Operation in the Expression.
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 * 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.
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 * 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="")
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)
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 isFreeToInvert(Value *V, bool WillInvertAllUses)
Return true if the specified value is free to invert (apply ~ to).
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
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-ze