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))) &&
1115 auto *SelEltTy = dyn_cast<IntegerType>(SelTy->
getScalarType());
1116 if (!SelEltTy || SelTy->
isVectorTy() !=
Cmp.getType()->isVectorTy())
1129 if ((CmpLHS == TrueVal && AdjustedRHS == FalseVal) ||
1130 (CmpLHS == FalseVal && AdjustedRHS == TrueVal)) {
1145 AdjustedRHS = SextRHS;
1147 SextRHS == TrueVal) {
1149 AdjustedRHS = SextRHS;
1150 }
else if (
Cmp.isUnsigned()) {
1158 AdjustedRHS = ZextRHS;
1160 ZextRHS == TrueVal) {
1162 AdjustedRHS = ZextRHS;
1174 CmpRHS = AdjustedRHS;
1176 Cmp.setPredicate(Pred);
1177 Cmp.setOperand(0, CmpLHS);
1178 Cmp.setOperand(1, CmpRHS);
1185 Cmp.moveBefore(&Sel);
1220 IntrinsicID = Intrinsic::umin;
1223 IntrinsicID = Intrinsic::umax;
1226 IntrinsicID = Intrinsic::smin;
1229 IntrinsicID = Intrinsic::smax;
1247 auto *
I = dyn_cast<Instruction>(V);
1251 bool Changed =
false;
1252 for (
Use &U :
I->operands()) {
1257 Changed |= replaceInInstruction(U, Old, New, IC,
Depth + 1);
1281 if (!
Cmp.isEquality())
1286 bool Swapped =
false;
1297 Value *CmpLHS =
Cmp.getOperand(0), *CmpRHS =
Cmp.getOperand(1);
1298 if (TrueVal != CmpLHS &&
1312 !
Cmp.getType()->isVectorTy())
1313 if (replaceInInstruction(TrueVal, CmpLHS, CmpRHS, *
this))
1316 if (TrueVal != CmpRHS &&
1322 auto *FalseInst = dyn_cast<Instruction>(FalseVal);
1329 bool WasNUW =
false, WasNSW =
false, WasExact =
false, WasInBounds =
false;
1330 if (
auto *OBO = dyn_cast<OverflowingBinaryOperator>(FalseVal)) {
1331 WasNUW = OBO->hasNoUnsignedWrap();
1332 WasNSW = OBO->hasNoSignedWrap();
1333 FalseInst->setHasNoUnsignedWrap(
false);
1334 FalseInst->setHasNoSignedWrap(
false);
1336 if (
auto *PEO = dyn_cast<PossiblyExactOperator>(FalseVal)) {
1337 WasExact = PEO->isExact();
1338 FalseInst->setIsExact(
false);
1340 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(FalseVal)) {
1341 WasInBounds =
GEP->isInBounds();
1342 GEP->setIsInBounds(
false);
1350 false) == TrueVal ||
1352 false) == TrueVal) {
1358 FalseInst->setHasNoUnsignedWrap();
1360 FalseInst->setHasNoSignedWrap();
1362 FalseInst->setIsExact();
1364 cast<GetElementPtrInst>(FalseInst)->setIsInBounds();
1399 if (!isa<SelectInst>(Sel1)) {
1440 if (Cmp00->
getType() !=
X->getType() &&
X->hasOneUse())
1448 else if (!
match(Cmp00,
1456 Value *ReplacementLow, *ReplacementHigh;
1493 std::swap(ReplacementLow, ReplacementHigh);
1499 "Unexpected predicate type.");
1507 "Unexpected predicate type.");
1509 std::swap(ThresholdLowIncl, ThresholdHighExcl);
1525 if (
X->getType() != Sel0.
getType()) {
1535 Value *ShouldReplaceLow =
Builder.CreateICmpSLT(
X, ThresholdLowIncl);
1536 Value *ShouldReplaceHigh =
Builder.CreateICmpSGE(
X, ThresholdHighExcl);
1537 Value *MaybeReplacedLow =
1538 Builder.CreateSelect(ShouldReplaceLow, ReplacementLow,
X);
1543 ShouldReplaceHigh, ReplacementHigh, MaybeReplacedLow);
1587 Value *SelVal0, *SelVal1;
1596 auto MatchesSelectValue = [SelVal0, SelVal1](
Constant *
C) {
1597 return C->isElementWiseEqual(SelVal0) ||
C->isElementWiseEqual(SelVal1);
1601 if (MatchesSelectValue(C0))
1605 auto FlippedStrictness =
1607 if (!FlippedStrictness)
1611 if (!MatchesSelectValue(FlippedStrictness->second))
1620 Cmp.getName() +
".inv");
1631 if (!
Cmp->hasOneUse())
1661 Value *TVal =
SI.getTrueValue();
1662 Value *FVal =
SI.getFalseValue();
1666 return Builder.CreateBinaryIntrinsic(Intrinsic::umax, V, TVal);
1669 return Builder.CreateBinaryIntrinsic(Intrinsic::umin, V, TVal);
1672 return Builder.CreateBinaryIntrinsic(Intrinsic::smax, V, TVal);
1675 return Builder.CreateBinaryIntrinsic(Intrinsic::smin, V, TVal);
1688 const APInt *BinOpC;
1707 if (
Instruction *NewSPF = canonicalizeSPF(SI, *ICI, *
this))
1710 if (
Value *V = foldSelectInstWithICmpConst(SI, ICI,
Builder))
1713 if (
Value *V = canonicalizeClampLike(SI, *ICI,
Builder))
1717 tryToReuseConstantFromSelectInComparison(SI, *ICI, *
this))
1720 bool Changed = adjustMinMax(SI, *ICI);
1731 if (CmpRHS != CmpLHS && isa<Constant>(CmpRHS) && !isa<Constant>(CmpLHS)) {
1734 SI.setOperand(1, CmpRHS);
1738 SI.setOperand(2, CmpRHS);
1755 SI.swapProfMetadata();
1761 if (
TrueVal->getType()->isIntOrIntVectorTy()) {
1768 bool IsBitTest =
false;
1776 Y = &MinSignedValue;
1778 TrueWhenUnset =
false;
1781 Y = &MinSignedValue;
1783 TrueWhenUnset =
true;
1788 if (TrueWhenUnset && TrueVal ==
X &&
1792 else if (!TrueWhenUnset && FalseVal ==
X &&
1796 else if (TrueWhenUnset && FalseVal ==
X &&
1800 else if (!TrueWhenUnset && TrueVal ==
X &&
1825 if (
Value *V = foldSelectCttzCtlz(ICI, TrueVal, FalseVal,
Builder))
1837 return Changed ? &
SI :
nullptr;
1849static bool canSelectOperandBeMappingIntoPredBlock(
const Value *V,
1854 if (!
I)
return true;
1858 const PHINode *CondPHI = cast<PHINode>(
SI.getCondition());
1860 if (
const PHINode *VP = dyn_cast<PHINode>(
I))
1861 if (VP->getParent() == CondPHI->
getParent())
1885 if (
C ==
A ||
C ==
B) {
1900 Value *CondVal =
SI.getCondition();
1903 auto *TI = dyn_cast<Instruction>(TrueVal);
1904 auto *FI = dyn_cast<Instruction>(FalseVal);
1905 if (!TI || !FI || !TI->hasOneUse() || !FI->hasOneUse())
1909 if ((TI->getOpcode() == Instruction::Sub &&
1910 FI->getOpcode() == Instruction::Add) ||
1911 (TI->getOpcode() == Instruction::FSub &&
1912 FI->getOpcode() == Instruction::FAdd)) {
1915 }
else if ((FI->getOpcode() == Instruction::Sub &&
1916 TI->getOpcode() == Instruction::Add) ||
1917 (FI->getOpcode() == Instruction::FSub &&
1918 TI->getOpcode() == Instruction::FAdd)) {
1924 Value *OtherAddOp =
nullptr;
1925 if (SubOp->getOperand(0) == AddOp->
getOperand(0)) {
1927 }
else if (SubOp->getOperand(0) == AddOp->
getOperand(1)) {
1935 if (
SI.getType()->isFPOrFPVectorTy()) {
1936 NegVal =
Builder.CreateFNeg(SubOp->getOperand(1));
1937 if (
Instruction *NegInst = dyn_cast<Instruction>(NegVal)) {
1939 Flags &= SubOp->getFastMathFlags();
1940 NegInst->setFastMathFlags(Flags);
1943 NegVal =
Builder.CreateNeg(SubOp->getOperand(1));
1946 Value *NewTrueOp = OtherAddOp;
1947 Value *NewFalseOp = NegVal;
1950 Value *NewSel =
Builder.CreateSelect(CondVal, NewTrueOp, NewFalseOp,
1951 SI.getName() +
".p", &SI);
1953 if (
SI.getType()->isFPOrFPVectorTy()) {
1955 BinaryOperator::CreateFAdd(SubOp->getOperand(0), NewSel);
1958 Flags &= SubOp->getFastMathFlags();
1962 return BinaryOperator::CreateAdd(SubOp->getOperand(0), NewSel);
1975 Value *CondVal =
SI.getCondition();
1987 auto IsSignedSaturateLimit = [&](
Value *Limit,
bool IsAdd) {
1997 auto IsZeroOrOne = [](
const APInt &
C) {
return C.isZero() ||
C.isOne(); };
2005 if (Op !=
X && Op !=
Y)
2014 IsMinMax(TrueVal, FalseVal))
2021 IsMinMax(FalseVal, TrueVal))
2027 IsMinMax(TrueVal, FalseVal))
2032 IsMinMax(FalseVal, TrueVal))
2037 IsMinMax(FalseVal, TrueVal))
2042 IsMinMax(TrueVal, FalseVal))
2053 NewIntrinsicID = Intrinsic::uadd_sat;
2054 else if (II->
getIntrinsicID() == Intrinsic::usub_with_overflow &&
2057 NewIntrinsicID = Intrinsic::usub_sat;
2058 else if (II->
getIntrinsicID() == Intrinsic::sadd_with_overflow &&
2059 IsSignedSaturateLimit(TrueVal,
true))
2068 NewIntrinsicID = Intrinsic::sadd_sat;
2069 else if (II->
getIntrinsicID() == Intrinsic::ssub_with_overflow &&
2070 IsSignedSaturateLimit(TrueVal,
false))
2079 NewIntrinsicID = Intrinsic::ssub_sat;
2100 if (ExtOpcode != Instruction::ZExt && ExtOpcode != Instruction::SExt)
2106 Type *SmallType =
X->getType();
2108 auto *
Cmp = dyn_cast<CmpInst>(
Cond);
2110 (!Cmp ||
Cmp->getOperand(0)->getType() != SmallType))
2119 Value *TruncCVal = cast<Value>(TruncC);
2152 Value *CondVal =
SI.getCondition();
2154 auto *CondValTy = dyn_cast<FixedVectorType>(CondVal->
getType());
2158 unsigned NumElts = CondValTy->getNumElements();
2160 Mask.reserve(NumElts);
2161 for (
unsigned i = 0; i != NumElts; ++i) {
2171 Mask.push_back(i + NumElts);
2172 }
else if (isa<UndefValue>(Elt)) {
2192 auto *Ty = dyn_cast<VectorType>(Sel.
getType());
2224 if (TVal ==
A || TVal ==
B || FVal ==
A || FVal ==
B)
2241 if (TSrc ==
C && FSrc ==
D) {
2245 }
else if (TSrc ==
D && FSrc ==
C) {
2284 auto *Extract = dyn_cast<ExtractValueInst>(V);
2287 if (Extract->getIndices()[0] !=
I)
2289 return dyn_cast<AtomicCmpXchgInst>(Extract->getAggregateOperand());
2295 if (
auto *
Select = dyn_cast<SelectInst>(
SI.user_back()))
2296 if (
Select->getCondition() ==
SI.getCondition())
2297 if (
Select->getFalseValue() ==
SI.getTrueValue() ||
2298 Select->getTrueValue() ==
SI.getFalseValue())
2302 auto *CmpXchg = isExtractFromCmpXchg(
SI.getCondition(), 1);
2309 if (
auto *
X = isExtractFromCmpXchg(
SI.getTrueValue(), 0))
2310 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getFalseValue())
2311 return SI.getFalseValue();
2316 if (
auto *
X = isExtractFromCmpXchg(
SI.getFalseValue(), 0))
2317 if (
X == CmpXchg &&
X->getCompareOperand() ==
SI.getTrueValue())
2318 return SI.getFalseValue();
2342 Value *SV0, *SV1, *SA0, *SA1;
2351 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2357 Or1->
getOpcode() == BinaryOperator::LShr &&
2358 "Illegal or(shift,shift) pair");
2373 bool IsFshl = (ShAmt == SA0);
2375 if ((IsFshl && TVal != SV0) || (!IsFshl && TVal != SV1))
2389 SV1 =
Builder.CreateFreeze(SV1);
2391 SV0 =
Builder.CreateFreeze(SV0);
2396 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
2417 assert(TC != FC &&
"Expected equal select arms to simplify");
2421 bool IsTrueIfSignSet;
2425 X->getType() != SelType)
2446 if (!isa<VectorType>(Sel.
getType()))
2457 if (
auto *
I = dyn_cast<Instruction>(V))
2458 I->copyIRFlags(&Sel);
2461 M, Intrinsic::experimental_vector_reverse,
V->getType());
2469 return createSelReverse(
C,
X,
Y);
2473 return createSelReverse(
C,
X, FVal);
2478 return createSelReverse(
C, TVal,
Y);
2481 auto *VecTy = dyn_cast<FixedVectorType>(Sel.
getType());
2485 unsigned NumElts = VecTy->getNumElements();
2486 APInt UndefElts(NumElts, 0);
2500 cast<ShuffleVectorInst>(TVal)->isSelect()) {
2514 cast<ShuffleVectorInst>(FVal)->isSelect()) {
2535 auto *IDomNode = DT[BB]->getIDom();
2541 Value *IfTrue, *IfFalse;
2557 if (TrueSucc == FalseSucc)
2573 else if (DT.
dominates(FalseEdge, Incoming))
2578 if (
auto *
Insn = dyn_cast<Instruction>(Inputs[Pred]))
2586 PN->addIncoming(Inputs[Pred], Pred);
2597 if (
auto *
I = dyn_cast<Instruction>(V))
2598 CandidateBlocks.
insert(
I->getParent());
2601 if (
auto *PN = foldSelectToPhiImpl(Sel, BB, DT, Builder))
2635 Value *CondVal =
SI.getCondition();
2639 assert(
Op->getType()->isIntOrIntVectorTy(1) &&
2640 "Op must be either i1 or vector of i1.");
2678 Value *CondVal =
SI.getCondition();
2680 bool ChangedFMF =
false;
2681 for (
bool Swap : {
false,
true}) {
2711 FastMathFlags FMF = cast<FPMathOperator>(TrueVal)->getFastMathFlags();
2712 if (FMF.
noNaNs() && !
SI.hasNoNaNs()) {
2713 SI.setHasNoNaNs(
true);
2716 if (FMF.
noInfs() && !
SI.hasNoInfs()) {
2717 SI.setHasNoInfs(
true);
2731 if (!
SI.hasNoSignedZeros() || !
SI.hasNoNaNs())
2748 Instruction *NewFNeg = UnaryOperator::CreateFNeg(Fabs);
2754 return ChangedFMF ? &
SI :
nullptr;
2772foldRoundUpIntegerWithPow2Alignment(
SelectInst &SI,
2776 Value *XBiasedHighBits =
SI.getFalseValue();
2789 const APInt *LowBitMaskCst;
2794 const APInt *BiasCst, *HighBitMaskCst;
2795 if (!
match(XBiasedHighBits,
2798 !
match(XBiasedHighBits,
2803 if (!LowBitMaskCst->
isMask())
2806 APInt InvertedLowBitMaskCst = ~*LowBitMaskCst;
2807 if (InvertedLowBitMaskCst != *HighBitMaskCst)
2810 APInt AlignmentCst = *LowBitMaskCst + 1;
2812 if (*BiasCst != AlignmentCst && *BiasCst != *LowBitMaskCst)
2816 if (*BiasCst == *LowBitMaskCst)
2817 return XBiasedHighBits;
2822 Type *Ty =
X->getType();
2824 X->getName() +
".biased");
2831struct DecomposedSelect {
2848 DecomposedSelect OuterSel;
2855 std::swap(OuterSel.TrueVal, OuterSel.FalseVal);
2863 Value *InnerSelVal = IsAndVariant ? OuterSel.FalseVal : OuterSel.TrueVal;
2867 [](
Value *V) {
return V->hasOneUse(); }))
2871 DecomposedSelect InnerSel;
2872 if (!
match(InnerSelVal,
2879 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
2881 Value *AltCond =
nullptr;
2882 auto matchOuterCond = [OuterSel, &AltCond](
auto m_InnerCond) {
2890 if (matchOuterCond(
m_Specific(InnerSel.Cond))) {
2895 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
2896 InnerSel.Cond = NotInnerCond;
2901 AltCond, IsAndVariant ? OuterSel.TrueVal : InnerSel.FalseVal,
2902 IsAndVariant ? InnerSel.TrueVal : OuterSel.FalseVal);
2905 IsAndVariant ? SelInner : InnerSel.TrueVal,
2906 !IsAndVariant ? SelInner : InnerSel.FalseVal);
2910 Value *CondVal =
SI.getCondition();
2913 Type *SelType =
SI.getType();
2932 return BinaryOperator::CreateOr(CondVal, FalseVal);
2935 if (
auto *LHS = dyn_cast<FCmpInst>(CondVal))
2936 if (
auto *RHS = dyn_cast<FCmpInst>(FalseVal))
2937 if (
Value *V = foldLogicOfFCmps(LHS, RHS,
false,
2945 bool CondLogicAnd = isa<SelectInst>(CondVal);
2946 bool FalseLogicAnd = isa<SelectInst>(FalseVal);
2947 auto AndFactorization = [&](
Value *Common,
Value *InnerCond,
2953 if (FalseLogicAnd || (CondLogicAnd && Common ==
A))
2956 return BinaryOperator::CreateAnd(Common, InnerSel);
2960 return AndFactorization(
A,
B,
D);
2962 return AndFactorization(
A,
B,
C);
2964 return AndFactorization(
B,
A,
D);
2966 return AndFactorization(
B,
A,
C, CondLogicAnd && FalseLogicAnd);
2973 return BinaryOperator::CreateAnd(CondVal, TrueVal);
2976 if (
auto *LHS = dyn_cast<FCmpInst>(CondVal))
2977 if (
auto *RHS = dyn_cast<FCmpInst>(TrueVal))
2978 if (
Value *V = foldLogicOfFCmps(LHS, RHS,
true,
2986 bool CondLogicOr = isa<SelectInst>(CondVal);
2987 bool TrueLogicOr = isa<SelectInst>(TrueVal);
2988 auto OrFactorization = [&](
Value *Common,
Value *InnerCond,
2994 if (TrueLogicOr || (CondLogicOr && Common ==
A))
2997 return BinaryOperator::CreateOr(Common, InnerSel);
3001 return OrFactorization(
A,
B,
D);
3003 return OrFactorization(
A,
B,
C);
3005 return OrFactorization(
B,
A,
D);
3007 return OrFactorization(
B,
A,
C, CondLogicOr && TrueLogicOr);
3058 return BinaryOperator::CreateXor(
A,
B);
3078 auto *FI =
new FreezeInst(*
Y, (*Y)->getName() +
".fr");
3084 if (
auto *Op1SI = dyn_cast<SelectInst>(Op1))
3085 if (
auto *
I = foldAndOrOfSelectUsingImpliedCond(CondVal, *Op1SI,
3089 if (
auto *ICmp0 = dyn_cast<ICmpInst>(CondVal))
3090 if (
auto *ICmp1 = dyn_cast<ICmpInst>(Op1))
3091 if (
auto *V = foldAndOrOfICmps(ICmp0, ICmp1, SI, IsAnd,
3102 if (Res && *Res ==
false)
3108 if (Res && *Res ==
false)
3117 if (Res && *Res ==
true)
3123 if (Res && *Res ==
true)
3136 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3137 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3138 bool MayNeedFreeze = SelCond && SelFVal &&
3139 match(SelFVal->getTrueValue(),
3152 auto *SelCond = dyn_cast<SelectInst>(CondVal);
3153 auto *SelFVal = dyn_cast<SelectInst>(FalseVal);
3154 bool MayNeedFreeze = SelCond && SelFVal &&
3155 match(SelCond->getTrueValue(),
3197 auto MatchForward = [&](
Value *CommonAncestor) {
3198 const APInt *
C =
nullptr;
3199 if (CtlzOp == CommonAncestor)
3216 const APInt *
C =
nullptr;
3217 Value *CommonAncestor;
3218 if (MatchForward(Cond0)) {
3222 if (!MatchForward(CommonAncestor))
3259 Type *SelType =
SI.getType();
3266 Value *Cond0, *Ctlz, *CtlzOp;
3280 !isSafeToRemoveBitCeilSelect(Pred, Cond0, Cond1, CtlzOp,
BitWidth))
3295 Value *CondVal =
SI.getCondition();
3298 Type *SelType =
SI.getType();
3307 if (
Instruction *
I = canonicalizeScalarSelectOfVecs(SI, *
this))
3365 return new ZExtInst(CondVal, SelType);
3369 return new SExtInst(CondVal, SelType);
3374 return new ZExtInst(NotCond, SelType);
3380 return new SExtInst(NotCond, SelType);
3384 if (
auto *FCmp = dyn_cast<FCmpInst>(CondVal)) {
3387 if ((Cmp0 == TrueVal && Cmp1 == FalseVal) ||
3388 (Cmp0 == FalseVal && Cmp1 == TrueVal)) {
3400 FCmp->getName() +
".inv");
3407 if (isa<FPMathOperator>(SI)) {
3412 if (
SI.hasNoNaNs() &&
SI.hasNoSignedZeros()) {
3425 if (
Instruction *Fabs = foldSelectWithFCmpToFabs(SI, *
this))
3429 if (
ICmpInst *ICI = dyn_cast<ICmpInst>(CondVal))
3443 auto *TI = dyn_cast<Instruction>(TrueVal);
3444 auto *FI = dyn_cast<Instruction>(FalseVal);
3445 if (TI && FI && TI->getOpcode() == FI->
getOpcode())
3461 if (isa<VectorType>(CondVal->
getType()) && !isa<VectorType>(
Idx->getType()))
3472 if (
auto *TrueGep = dyn_cast<GetElementPtrInst>(TrueVal))
3473 if (
auto *NewGep = SelectGepWithBase(TrueGep, FalseVal,
false))
3475 if (
auto *FalseGep = dyn_cast<GetElementPtrInst>(FalseVal))
3476 if (
auto *NewGep = SelectGepWithBase(FalseGep, TrueVal,
true))
3492 RHS2, SI, SPF, RHS))
3496 RHS2, SI, SPF, LHS))
3505 bool IsCastNeeded =
LHS->
getType() != SelType;
3506 Value *CmpLHS = cast<CmpInst>(CondVal)->getOperand(0);
3507 Value *CmpRHS = cast<CmpInst>(CondVal)->getOperand(1);
3510 ((CmpLHS != LHS && CmpLHS != RHS) ||
3511 (CmpRHS != LHS && CmpRHS != RHS)))) {
3520 cast<FPMathOperator>(
SI.getCondition())->getFastMathFlags();
3536 if (
auto *PN = dyn_cast<PHINode>(
SI.getCondition()))
3538 if (canSelectOperandBeMappingIntoPredBlock(TrueVal, SI) &&
3539 canSelectOperandBeMappingIntoPredBlock(FalseVal, SI))
3543 if (
SelectInst *TrueSI = dyn_cast<SelectInst>(TrueVal)) {
3544 if (TrueSI->getCondition()->getType() == CondVal->
getType()) {
3546 if (TrueSI->getCondition() == CondVal) {
3547 if (
SI.getTrueValue() == TrueSI->getTrueValue())
3555 if (TrueSI->getFalseValue() == FalseVal && TrueSI->hasOneUse()) {
3563 if (
SelectInst *FalseSI = dyn_cast<SelectInst>(FalseVal)) {
3564 if (FalseSI->getCondition()->getType() == CondVal->
getType()) {
3566 if (FalseSI->getCondition() == CondVal) {
3567 if (
SI.getFalseValue() == FalseSI->getFalseValue())
3572 if (FalseSI->getTrueValue() == TrueVal && FalseSI->hasOneUse()) {
3589 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(0))) {
3590 if (TrueBOSI->getCondition() == CondVal) {
3596 if (
auto *TrueBOSI = dyn_cast<SelectInst>(TrueBO->
getOperand(1))) {
3597 if (TrueBOSI->getCondition() == CondVal) {
3608 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(0))) {
3609 if (FalseBOSI->getCondition() == CondVal) {
3615 if (
auto *FalseBOSI = dyn_cast<SelectInst>(FalseBO->
getOperand(1))) {
3616 if (FalseBOSI->getCondition() == CondVal) {
3629 SI.swapProfMetadata();
3644 if (Known.One.isOne())
3646 if (Known.Zero.isOne())
3654 if (
Value *V = foldSelectCmpXchg(SI))
3672 if (
Value *V = foldRoundUpIntegerWithPow2Alignment(SI,
Builder))
3682 auto *MaskedInst = cast<IntrinsicInst>(TrueVal);
3683 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
3684 MaskedInst->setArgOperand(3, FalseVal );
3699 bool CanMergeSelectIntoLoad =
false;
3703 if (CanMergeSelectIntoLoad) {
3704 auto *MaskedInst = cast<IntrinsicInst>(FalseVal);
3705 if (isa<UndefValue>(MaskedInst->getArgOperand(3)))
3706 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 * getZExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getICmp(unsigned short pred, Constant *LHS, Constant *RHS, bool OnlyIfReduced=false)
get* - Return some common constants without having to specify the full Instruction::OPCODE identifier...
static Constant * getSExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)
Return the identity constant for a binary opcode.
static Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getNeg(Constant *C, bool HasNUW=false, bool HasNSW=false)
static Constant * get(Type *Ty, double V)
This returns a ConstantFP, or a vector containing a splat of a ConstantFP, for the specified value in...
static ConstantInt * getTrue(LLVMContext &Context)
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
static ConstantInt * getFalse(LLVMContext &Context)
This class represents a range of values.
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.
Instruction * foldSelectInstWithICmp(SelectInst &SI, ICmpInst *ICI)
bool sinkNotIntoOtherHandOfLogicalOp(Instruction &I)
Instruction * foldSelectIntoOp(SelectInst &SI, Value *, Value *)
Try to fold the select into one of the operands to allow further optimization.
Instruction * visitSelectInst(SelectInst &SI)
Instruction * foldSelectOfBools(SelectInst &SI)
Instruction * foldSelectExtConst(SelectInst &Sel)
The core instruction combiner logic.
static bool isCanonicalPredicate(CmpInst::Predicate Pred)
Predicate canonicalization reduces the number of patterns that need to be matched by other transforms...
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
static bool shouldAvoidAbsorbingNotIntoSelect(const SelectInst &SI)
static std::optional< std::pair< CmpInst::Predicate, Constant * > > getFlippedStrictnessPredicateAndConstant(CmpInst::Predicate Pred, Constant *C)
void replaceUse(Use &U, Value *NewValue)
Replace use and add the previously used value to the worklist.
InstructionWorklist & Worklist
A worklist of the instructions that need to be simplified.
Instruction * InsertNewInstBefore(Instruction *New, Instruction &Old)
Inserts an instruction New before instruction Old.
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
static bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS, bool &TrueIfSigned)
Given an exploded icmp instruction, return true if the comparison only checks the sign bit.
void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth, const Instruction *CxtI) const
static Constant * AddOne(Constant *C)
Add one to a Constant.
void push(Instruction *I)
Push the instruction onto the worklist stack.
bool isSameOperationAs(const Instruction *I, unsigned flags=0) const LLVM_READONLY
This function determines if the specified instruction executes the same operation as the current one.
bool hasNoSignedZeros() const LLVM_READONLY
Determine whether the no-signed-zeros flag is set.
void copyIRFlags(const Value *V, bool IncludeWrapFlags=true)
Convenience method to copy supported exact, fast-math, and (optionally) wrapping flags from V to this...
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction.
bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
const BasicBlock * getParent() const
void swapProfMetadata()
If the instruction has "branch_weights" MD_prof metadata and the MDNode has three operands (including...
FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void dropPoisonGeneratingFlags()
Drops flags that may cause this instruction to evaluate to poison despite having non-poison inputs.
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
A Module instance is used to store all the information related to an LLVM module.
This class represents a sign extension of integer types.
This class represents the LLVM 'select' instruction.
const Value * getFalseValue() const
void swapValues()
Swap the true and false values of the select instruction.
const Value * getCondition() const
const Value * getTrueValue() const
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", Instruction *InsertBefore=nullptr, Instruction *MDFrom=nullptr)
bool insert(const value_type &X)
Insert a new element into the SetVector.
This instruction constructs a fixed permutation of two input vectors.
A SetVector that performs no allocations if smaller than a certain size.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Provides information about what library functions are available for the current target.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
static IntegerType * getInt1Ty(LLVMContext &C)
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
A Use represents the edge between a Value definition and its users.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
const Value * DoPHITranslation(const BasicBlock *CurBB, const BasicBlock *PredBB) const
Translate PHI node to its predecessor from the given basic block.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVMContext & getContext() const
All values hold a context through their type.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
Represents an op.with.overflow intrinsic.
This class represents zero extension of integer types.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
specific_intval< false > m_SpecificInt(APInt V)
Match a specific integer value or vector with all elements equal to the value.
match_combine_or< CastClass_match< OpTy, Instruction::ZExt >, OpTy > m_ZExtOrSelf(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
apfloat_match m_APFloatAllowUndef(const APFloat *&Res)
Match APFloat while allowing undefs in splat vector constants.
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
apint_match m_APIntAllowUndef(const APInt *&Res)
Match APInt while allowing undefs in splat vector constants.
CastClass_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
BinaryOp_match< LHS, RHS, Instruction::FSub > m_FSub(const LHS &L, const RHS &R)
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power-of-2.
CastClass_match< OpTy, Instruction::SExt > m_SExt(const OpTy &Op)
Matches SExt.
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
CastClass_match< OpTy, Instruction::ZExt > m_ZExt(const OpTy &Op)
Matches ZExt.
bool match(Val *V, const Pattern &P)
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
constantexpr_match m_ConstantExpr()
Match a constant expression or a constant that contains a constant expression.
OverflowingBinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWNeg(const ValTy &V)
Matches a 'Neg' as 'sub nsw 0, V'.