51#define DEBUG_TYPE "instcombine"
89 bool IsAbsorbingValue =
false;
101 IsAbsorbingValue =
true;
114 if (IsAbsorbingValue) {
129 if (!FPO->hasNoSignedZeros() &&
157 const APInt *SelTC, *SelFC;
166 const APInt &TC = *SelTC;
167 const APInt &FC = *SelFC;
168 if (!TC.
isZero() && !FC.isZero()) {
180 Constant *TCC = ConstantInt::get(SelType, TC);
181 Constant *FCC = ConstantInt::get(SelType, FC);
182 Constant *MaskC = ConstantInt::get(SelType, AndMask);
183 for (
auto Opc : {Instruction::Or, Instruction::Xor, Instruction::Add,
188 V = Builder.CreateAnd(
V, MaskC);
189 return Builder.CreateBinOp(
Opc, TCC,
V);
203 unsigned ValZeros = ValC.
logBase2();
204 unsigned AndZeros = AndMask.
logBase2();
205 bool ShouldNotVal = !TC.
isZero();
206 bool NeedShift = ValZeros != AndZeros;
213 if (CreateAnd + ShouldNotVal + NeedShift + NeedZExtTrunc >
219 V = Builder.CreateAnd(
V, ConstantInt::get(
V->getType(), AndMask));
223 if (ValZeros > AndZeros) {
224 V = Builder.CreateZExtOrTrunc(
V, SelType);
225 V = Builder.CreateShl(
V, ValZeros - AndZeros);
226 }
else if (ValZeros < AndZeros) {
227 V = Builder.CreateLShr(
V, AndZeros - ValZeros);
228 V = Builder.CreateZExtOrTrunc(
V, SelType);
230 V = Builder.CreateZExtOrTrunc(
V, SelType);
236 V = Builder.CreateXor(
V, ValC);
252 switch (
I->getOpcode()) {
253 case Instruction::Add:
254 case Instruction::FAdd:
255 case Instruction::Mul:
256 case Instruction::FMul:
257 case Instruction::And:
258 case Instruction::Or:
259 case Instruction::Xor:
261 case Instruction::Sub:
262 case Instruction::FSub:
263 case Instruction::FDiv:
264 case Instruction::Shl:
265 case Instruction::LShr:
266 case Instruction::AShr:
288 CondVTy->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;
368 FMF |=
SI.getFastMathFlags();
372 NewSelI->setFastMathFlags(FMF);
373 Instruction *NewFNeg = UnaryOperator::CreateFNeg(NewSel);
384 if (
TII && FII &&
TII->getIntrinsicID() == FII->getIntrinsicID()) {
386 if (
Value *MatchOp = getCommonOp(TI, FI,
true)) {
388 Builder.CreateSelect(
Cond, OtherOpT, OtherOpF,
"minmaxop", &
SI);
398 if (
TII->getIntrinsicID() == Intrinsic::ldexp) {
399 Value *LdexpVal0 =
TII->getArgOperand(0);
400 Value *LdexpExp0 =
TII->getArgOperand(1);
401 Value *LdexpVal1 = FII->getArgOperand(0);
402 Value *LdexpExp1 = FII->getArgOperand(1);
410 Cond, LdexpVal0, LdexpVal1,
"",
413 Cond, LdexpExp0, LdexpExp1,
"",
417 TII->getType(), Intrinsic::ldexp, {SelectVal, SelectExp}, FMF);
423 auto CreateCmpSel = [&](std::optional<CmpPredicate>
P,
432 SI.getName() +
".v", &
SI);
486 if (BO->getOpcode() == Instruction::SDiv ||
487 BO->getOpcode() == Instruction::SRem || MatchIsOpZero)
493 SI.getName() +
".v", &
SI);
494 Value *Op0 = MatchIsOpZero ? MatchOp : NewSI;
495 Value *Op1 = MatchIsOpZero ? NewSI : MatchOp;
504 Type *ElementType = TGEP->getSourceElementType();
506 ElementType, Op0, Op1, TGEP->getNoWrapFlags() & FGEP->getNoWrapFlags());
520 std::optional<unsigned> DiffArgNo;
521 for (
unsigned I = 0,
E =
TII->arg_size();
I !=
E; ++
I) {
534 Value *TV =
TII->getArgOperand(*DiffArgNo);
537 if (
SI.getCondition()->getType()->isVectorTy() &&
546 Builder.CreateSelect(
SI.getCondition(), TV, FV,
SI.getName() +
".v", &
SI);
548 NewCall->copyIRFlags(
TII);
549 NewCall->andIRFlags(FII);
563 LHSIntrinsic->getIntrinsicID() != RHSIntrinsic->getIntrinsicID() ||
564 !LHSIntrinsic->hasOneUse() || !RHSIntrinsic->hasOneUse())
570 case Intrinsic::cttz:
571 case Intrinsic::ctlz: {
575 Value *TV = LHSIntrinsic->getArgOperand(0);
576 Value *FV = RHSIntrinsic->getArgOperand(0);
580 Value *NewCall =
Builder.CreateBinaryIntrinsic(IID, NewSel, NewPoisonFlag);
612 unsigned OpToFold = 0;
613 if ((SFO & 1) && FalseVal == TVI->getOperand(0))
615 else if ((SFO & 2) && FalseVal == TVI->getOperand(1))
623 FMF = FPO->getFastMathFlags();
625 TVI->getOpcode(), TVI->getType(),
true, FMF.
noSignedZeros());
626 Value *OOp = TVI->getOperand(2 - OpToFold);
632 (!OOpIsAPInt || !
isSelect01(
C->getUniqueInteger(), *OOpC)))
646 Value *NewSel =
Builder.CreateSelect(
SI.getCondition(), Swapped ?
C : OOp,
647 Swapped ? OOp :
C,
"", &
SI);
658 bool CanInferFiniteOperandsFromResult =
659 TVI->getOpcode() == Instruction::FAdd ||
660 TVI->getOpcode() == Instruction::FSub ||
661 TVI->getOpcode() == Instruction::FMul;
663 (CanInferFiniteOperandsFromResult &&
682 if (
Instruction *R = TryFoldSelectIntoOp(
SI, TrueVal, FalseVal,
false))
685 if (
Instruction *R = TryFoldSelectIntoOp(
SI, FalseVal, TrueVal,
true))
695 Value *CmpLHS = Cmp->getOperand(0);
696 Value *CmpRHS = Cmp->getOperand(1);
719 Builder.CreateBinaryIntrinsic(Intrinsic::smin, CmpRHS, CmpLHS);
720 return Builder.CreateNSWSub(CmpLHS,
SMin);
733 Value *CmpLHS = Cmp->getOperand(0);
734 Value *CmpRHS = Cmp->getOperand(1);
744 if (CmpRHS == TVal) {
757 return Builder.CreateBinaryIntrinsic(Intrinsic::smax, TVal, FVal);
763 return Builder.CreateBinaryIntrinsic(Intrinsic::smin, TVal, FVal);
769 return Builder.CreateBinaryIntrinsic(Intrinsic::umax, TVal, FVal);
779 return Builder.CreateBinaryIntrinsic(Intrinsic::umin, TVal, FVal);
798 unsigned NumReplaced = 1 +
Cond->hasOneUse();
800 Y = ConstantInt::get(
X->getType(), 1);
827 if (!
match(
A, TValPattern)) {
829 if (!
match(
A, TValPattern))
833 bool HasShift =
A !=
X;
835 NumReplaced += 1 + (HasShift &&
A->hasOneUse());
842 Constant *One = ConstantInt::get(SelType, 1);
843 Value *MaskB = HasShift ? Builder.CreateShl(One, Z) : One;
844 Value *FullMask = Builder.CreateOr(
Y, MaskB);
845 Value *MaskedX = Builder.CreateAnd(
X, FullMask);
846 Value *ICmpNeZero = Builder.CreateIsNotNull(MaskedX);
847 return new ZExtInst(ICmpNeZero, SelType);
876 C1->countLeadingZeros() !=
static_cast<unsigned>(C2->
getZExtValue()))
883 FI->setHasNoSignedWrap(
false);
884 FI->setHasNoUnsignedWrap(
false);
922 return Builder.CreateAShr(
X,
Y, IC->
getName(), IsExact);
950 const APInt &AndMask,
bool CreateAnd,
953 if (!TrueVal->getType()->isIntOrIntVectorTy())
956 unsigned C1Log = AndMask.
logBase2();
977 if (IdentityC ==
nullptr || !IdentityC->isNullValue())
982 bool NeedShift = C1Log != C2Log;
983 bool NeedZExtTrunc =
Y->getType()->getScalarSizeInBits() !=
984 V->getType()->getScalarSizeInBits();
991 if ((NeedShift + NeedXor + NeedZExtTrunc + CreateAnd) >
997 V = Builder.CreateAnd(
V, ConstantInt::get(
V->getType(), AndMask));
1000 if (C2Log > C1Log) {
1001 V = Builder.CreateZExtOrTrunc(
V,
Y->getType());
1002 V = Builder.CreateShl(
V, C2Log - C1Log);
1003 }
else if (C1Log > C2Log) {
1004 V = Builder.CreateLShr(
V, C1Log - C2Log);
1005 V = Builder.CreateZExtOrTrunc(
V,
Y->getType());
1007 V = Builder.CreateZExtOrTrunc(
V,
Y->getType());
1010 V = Builder.CreateXor(
V, *C2);
1012 auto *Res = Builder.CreateBinOp(BinOp->
getOpcode(),
Y,
V);
1014 BO->copyIRFlags(BinOp);
1033 Constant *OrC = ConstantInt::get(Ty, *
C);
1034 Value *NewSel = Builder.CreateSelect(
Cond, Zero, OrC,
"masksel", &Sel);
1035 return BinaryOperator::CreateOr(
T, NewSel);
1042 Constant *OrC = ConstantInt::get(Ty, *
C);
1043 Value *NewSel = Builder.CreateSelect(
Cond, OrC, Zero,
"masksel", &Sel);
1044 return BinaryOperator::CreateOr(
F, NewSel);
1065 auto *CondVal =
SI.getCondition();
1066 auto *TrueVal =
SI.getTrueValue();
1067 auto *FalseVal =
SI.getFalseValue();
1117 FalseValI->getOperand(0) ==
Y
1119 : (FalseValI->getOperand(1) ==
Y ? 1 : 2),
1129 const Value *FalseVal,
1149 return Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat,
A,
1150 ConstantInt::get(
A->getType(), 1));
1164 "Unexpected isUnsigned predicate!");
1170 bool IsNegative =
false;
1183 if (IsNegative && !TrueVal->hasOneUse() && !ICI->
hasOneUse())
1188 Value *Result = Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat,
A,
B);
1190 Result = Builder.CreateNeg(Result);
1196 const Value *FalseVal,
1213 return Builder.CreateBinaryIntrinsic(
1222 const Value *TrueVal,
1223 const Value *FalseVal,
1241 Value *Cmp0 = Cmp->getOperand(0);
1242 Value *Cmp1 = Cmp->getOperand(1);
1262 return Builder.CreateBinaryIntrinsic(
1263 Intrinsic::uadd_sat, Cmp0, ConstantInt::get(Cmp0->
getType(), 1));
1273 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp0,
1274 ConstantInt::get(Cmp0->
getType(), *
C));
1283 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp0,
1284 ConstantInt::get(Cmp0->
getType(), *
C));
1293 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp0,
1294 ConstantInt::get(Cmp0->
getType(), *
C));
1312 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat,
X,
Y);
1322 return Builder.CreateBinaryIntrinsic(
1332 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp1,
Y);
1342 Value *Cmp0 = Cmp->getOperand(0);
1343 Value *Cmp1 = Cmp->getOperand(1);
1365 return Builder.CreateBinaryIntrinsic(
1366 Intrinsic::sadd_sat, Cmp0, ConstantInt::get(Cmp0->
getType(), 1));
1371 return Builder.CreateBinaryIntrinsic(
1372 Intrinsic::sadd_sat, Cmp0,
1390 Pred = Flipped->first;
1391 Cmp1 = Flipped->second;
1395 APInt Threshold = *SatC - *
C;
1399 return Builder.CreateBinaryIntrinsic(
1400 Intrinsic::sadd_sat, Cmp0, ConstantInt::get(Cmp0->
getType(), *
C));
1413 Pred = Flipped->first;
1414 Cmp1 = Flipped->second;
1419 APInt Threshold = *SatC - *
C;
1423 return Builder.CreateBinaryIntrinsic(
1424 Intrinsic::sadd_sat, Cmp0, ConstantInt::get(Cmp0->
getType(), *
C));
1442 return Builder.CreateBinaryIntrinsic(Intrinsic::sadd_sat,
X, Cmp1);
1451 return Builder.CreateBinaryIntrinsic(Intrinsic::sadd_sat,
X, Cmp0);
1459 if (!Cmp->hasOneUse())
1481 Value *
A = Cmp->getOperand(0);
1482 Value *
B = Cmp->getOperand(1);
1495 (TI->hasNoSignedWrap() || TI->hasNoUnsignedWrap()) &&
1496 (FI->hasNoSignedWrap() || FI->hasNoUnsignedWrap())) {
1503 TI->setHasNoUnsignedWrap(
false);
1504 if (!TI->hasNoSignedWrap())
1505 TI->setHasNoSignedWrap(TI->hasOneUse());
1506 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, TI, Builder.getTrue());
1513 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, TI,
1514 Builder.getFalse());
1521 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, FI,
1522 Builder.getFalse());
1529 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, FI,
1530 Builder.getFalse());
1537 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, TI,
1538 Builder.getFalse());
1586 II->getModule(), Intrinsic::cttz,
II->getType());
1642 unsigned SizeOfInBits =
Count->getType()->getScalarSizeInBits();
1645 II->dropPoisonGeneratingAnnotations();
1657 II->dropUBImplyingAttrsAndMetadata();
1671static void dropPoisonGeneratingAnnotationsForSPFCanonicalization(
Value *
Cond,
1676 I->dropPoisonGeneratingAnnotations();
1679 I->dropPoisonGeneratingAnnotations();
1686 if (!
TrueVal->getType()->isIntOrIntVectorTy())
1711 dropPoisonGeneratingAnnotationsForSPFCanonicalization(&Cmp,
LHS,
RHS);
1727 if (!
I || !
I->hasOneUse() ||
1736 for (Use &U :
I->operands()) {
1769 bool Swapped =
false;
1770 if (
Cmp.isEquivalence(
true)) {
1773 }
else if (!
Cmp.isEquivalence()) {
1777 Value *CmpLHS =
Cmp.getOperand(0), *CmpRHS =
Cmp.getOperand(1);
1778 auto ReplaceOldOpWithNewOp = [&](
Value *OldOp,
1779 Value *NewOp) -> Instruction * {
1826 if (CanReplaceCmpLHSWithRHS) {
1827 if (Instruction *R = ReplaceOldOpWithNewOp(CmpLHS, CmpRHS))
1831 if (CanReplaceCmpRHSWithLHS) {
1832 if (Instruction *R = ReplaceOldOpWithNewOp(CmpRHS, CmpLHS))
1848 SmallVector<Instruction *> DropFlags;
1849 if ((CanReplaceCmpLHSWithRHS &&
1852 &DropFlags) == TrueVal) ||
1853 (CanReplaceCmpRHSWithLHS &&
1856 &DropFlags) == TrueVal)) {
1857 for (Instruction *
I : DropFlags) {
1858 I->dropPoisonGeneratingAnnotations();
1866 if (
FalseVal->getType()->isIntOrIntVectorTy(1) &&
1990 if (Cmp00->
getType() !=
X->getType() &&
X->hasOneUse())
1998 else if (!
match(Cmp00,
2006 Value *ReplacementLow, *ReplacementHigh;
2043 std::swap(ReplacementLow, ReplacementHigh);
2049 "Unexpected predicate type.");
2057 "Unexpected predicate type.");
2059 std::swap(ThresholdLowIncl, ThresholdHighExcl);
2075 if (
X->getType() != Sel0.
getType()) {
2085 assert(ReplacementLow && ReplacementHigh &&
2086 "Constant folding of ImmConstant cannot fail");
2104 ShouldReplaceHigh, ReplacementHigh, MaybeReplacedLow,
DEBUG_TYPE);
2148 Value *SelVal0, *SelVal1;
2157 auto MatchesSelectValue = [SelVal0, SelVal1](
Constant *
C) {
2158 return C->isElementWiseEqual(SelVal0) ||
C->isElementWiseEqual(SelVal1);
2162 if (MatchesSelectValue(
C0))
2167 if (!FlippedStrictness)
2171 if (!MatchesSelectValue(FlippedStrictness->second))
2180 Cmp.getName() +
".inv");
2191 if (!
Cmp->hasOneUse())
2221 Value *TVal =
SI.getTrueValue();
2222 Value *FVal =
SI.getFalseValue();
2256 Op->dropPoisonGeneratingFlags();
2261 MMI && MMI->getLHS() ==
V &&
match(MMI->getRHS(),
m_APInt(OpC))) {
2263 {InvDomCR, ConstantRange(*OpC)});
2265 MMI->dropPoisonGeneratingAnnotations();
2328 foldSelectWithExtremeEqCond(CmpLHS, CmpRHS, TrueVal, FalseVal))
2360 Opcode = BOp->getOpcode();
2361 IsIntrinsic =
false;
2375 Opcode =
II->getIntrinsicID();
2383 const DataLayout &
DL =
Cmp->getDataLayout();
2392 if (C3 == FoldBinaryOpOrIntrinsic(
C1, C2)) {
2395 }
else if (Flipped && C3 == FoldBinaryOpOrIntrinsic(Flipped->second, C2)) {
2397 RHS = Flipped->second;
2405 return Builder.CreateBinaryIntrinsic(Opcode, MinMax, C2);
2408 Value *BinOp =
Builder.CreateBinOp(BinOpc, MinMax, C2);
2413 if (BinOpc == Instruction::Add || BinOpc == Instruction::Sub ||
2414 BinOpc == Instruction::Mul) {
2417 willNotOverflow(BinOpc,
RHS, C2, *BinOpInst,
true))
2418 BinOpInst->setHasNoSignedWrap();
2420 willNotOverflow(BinOpc,
RHS, C2, *BinOpInst,
false))
2421 BinOpInst->setHasNoUnsignedWrap();
2439static Instruction *foldICmpUSubSatWithAndForMostSignificantBitCmp(
2445 const APInt *Constant1, *Constant2;
2463 auto *Ty =
A->getType();
2471 APInt AdjAP1 = *Constant1 - MostSignificantBit + 1;
2472 APInt AdjAP2 = *Constant2 - MostSignificantBit + 1;
2474 auto *Adj1 = ConstantInt::get(Ty, AdjAP1);
2475 auto *Adj2 = ConstantInt::get(Ty, AdjAP2);
2480 Constant *MSBConst = ConstantInt::get(Ty, MostSignificantBit);
2481 return BinaryOperator::CreateAnd(
Or, MSBConst);
2488 canonicalizeSPF(*ICI,
SI.getTrueValue(),
SI.getFalseValue(), *
this))
2491 if (
Value *
V = foldSelectInstWithICmpConst(SI, ICI,
Builder))
2494 if (
Value *
V = canonicalizeClampLike(SI, *ICI,
Builder, *
this))
2497 if (Instruction *NewSel =
2498 tryToReuseConstantFromSelectInComparison(SI, *ICI, *
this))
2500 if (Instruction *
Folded =
2501 foldICmpUSubSatWithAndForMostSignificantBitCmp(SI, ICI,
Builder))
2512 if (Instruction *NewSel = foldSelectICmpEq(SI, ICI, *
this))
2522 InstCombiner::BuilderTy::InsertPointGuard Guard(
Builder);
2527 SI.swapProfMetadata();
2532 SQ.getWithInstruction(&SI)))
2538 if (Instruction *
V = foldSelectCtlzToCttz(ICI, TrueVal, FalseVal,
Builder))
2541 if (Instruction *
V = foldSelectZeroOrOnes(ICI, TrueVal, FalseVal,
Builder))
2547 if (
Value *
V = foldSelectCttzCtlz(ICI, TrueVal, FalseVal, *
this))
2575 if (
C ==
A ||
C ==
B) {
2590 Value *CondVal =
SI.getCondition();
2595 if (!TI || !FI || !TI->hasOneUse() || !FI->hasOneUse())
2599 if ((TI->getOpcode() == Instruction::Sub &&
2600 FI->getOpcode() == Instruction::Add) ||
2601 (TI->getOpcode() == Instruction::FSub &&
2602 FI->getOpcode() == Instruction::FAdd)) {
2605 }
else if ((FI->getOpcode() == Instruction::Sub &&
2606 TI->getOpcode() == Instruction::Add) ||
2607 (FI->getOpcode() == Instruction::FSub &&
2608 TI->getOpcode() == Instruction::FAdd)) {
2614 Value *OtherAddOp =
nullptr;
2615 if (SubOp->getOperand(0) == AddOp->
getOperand(0)) {
2617 }
else if (SubOp->getOperand(0) == AddOp->
getOperand(1)) {
2625 if (
SI.getType()->isFPOrFPVectorTy()) {
2626 NegVal = Builder.
CreateFNeg(SubOp->getOperand(1));
2629 Flags &= SubOp->getFastMathFlags();
2630 NegInst->setFastMathFlags(Flags);
2633 NegVal = Builder.
CreateNeg(SubOp->getOperand(1));
2636 Value *NewTrueOp = OtherAddOp;
2637 Value *NewFalseOp = NegVal;
2641 SI.getName() +
".p", &
SI);
2643 if (
SI.getType()->isFPOrFPVectorTy()) {
2645 BinaryOperator::CreateFAdd(SubOp->getOperand(0), NewSel);
2648 Flags &= SubOp->getFastMathFlags();
2652 return BinaryOperator::CreateAdd(SubOp->getOperand(0), NewSel);
2665 Value *CondVal =
SI.getCondition();
2677 auto IsSignedSaturateLimit = [&](
Value *Limit,
bool IsAdd) {
2687 auto IsZeroOrOne = [](
const APInt &
C) {
return C.isZero() ||
C.isOne(); };
2704 IsMinMax(TrueVal, FalseVal))
2711 IsMinMax(FalseVal, TrueVal))
2717 IsMinMax(TrueVal, FalseVal))
2722 IsMinMax(FalseVal, TrueVal))
2727 IsMinMax(FalseVal, TrueVal))
2732 IsMinMax(TrueVal, FalseVal))
2740 if (
II->getIntrinsicID() == Intrinsic::uadd_with_overflow &&
2743 NewIntrinsicID = Intrinsic::uadd_sat;
2744 else if (
II->getIntrinsicID() == Intrinsic::usub_with_overflow &&
2747 NewIntrinsicID = Intrinsic::usub_sat;
2748 else if (
II->getIntrinsicID() == Intrinsic::sadd_with_overflow &&
2749 IsSignedSaturateLimit(TrueVal,
true))
2758 NewIntrinsicID = Intrinsic::sadd_sat;
2759 else if (
II->getIntrinsicID() == Intrinsic::ssub_with_overflow &&
2760 IsSignedSaturateLimit(TrueVal,
false))
2769 NewIntrinsicID = Intrinsic::ssub_sat;
2774 NewIntrinsicID,
SI.getType());
2790 if (ExtOpcode != Instruction::ZExt && ExtOpcode != Instruction::SExt)
2824 Value *CondVal =
SI.getCondition();
2830 unsigned NumElts = CondValTy->getNumElements();
2832 Mask.reserve(NumElts);
2833 for (
unsigned i = 0; i != NumElts; ++i) {
2843 Mask.push_back(i + NumElts);
2896 if (TVal ==
A || TVal ==
B || FVal ==
A || FVal ==
B)
2913 if (TSrc ==
C && FSrc ==
D) {
2917 }
else if (TSrc ==
D && FSrc ==
C) {
2965 V = BI->getOperand(0);
2969 if (Extract->getIndices()[0] !=
I)
2975 auto isCompareSameAsValue = [](
Value *CmpVal,
Value *SelVal) {
2983 return IntC && FpC && IntC->getValue() == FpC->getValue().bitcastToAPInt();
2990 if (
Select->getCondition() ==
SI.getCondition())
2991 if (
Select->getFalseValue() ==
SI.getTrueValue() ||
2992 Select->getTrueValue() ==
SI.getFalseValue())
2996 auto *CmpXchg = isExtractFromCmpXchg(
SI.getCondition(), 1);
3003 if (
auto *
X = isExtractFromCmpXchg(
SI.getTrueValue(), 0))
3005 isCompareSameAsValue(
X->getCompareOperand(),
SI.getFalseValue()))
3006 return SI.getFalseValue();
3011 if (
auto *
X = isExtractFromCmpXchg(
SI.getFalseValue(), 0))
3013 isCompareSameAsValue(
X->getCompareOperand(),
SI.getTrueValue()))
3014 return SI.getFalseValue();
3038 Value *SV0, *SV1, *SA0, *SA1;
3047 if (Or0->
getOpcode() == BinaryOperator::LShr) {
3053 Or1->
getOpcode() == BinaryOperator::LShr &&
3054 "Illegal or(shift,shift) pair");
3069 bool IsFshl = (ShAmt == SA0);
3071 if ((IsFshl && TVal != SV0) || (!IsFshl && TVal != SV1))
3091 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
3113 assert(TC != FC &&
"Expected equal select arms to simplify");
3117 bool IsTrueIfSignSet;
3135 Value *MagArg = ConstantFP::get(SelType,
abs(*TC));
3154 I->copyIRFlags(&Sel);
3157 M, Intrinsic::vector_reverse,
V->getType());
3165 return createSelReverse(
C,
X,
Y);
3169 return createSelReverse(
C,
X, FVal);
3174 return createSelReverse(
C, TVal,
Y);
3181 unsigned NumElts = VecTy->getNumElements();
3182 APInt PoisonElts(NumElts, 0);
3200 return new ShuffleVectorInst(
X, NewSel, Mask);
3205 return new ShuffleVectorInst(NewSel,
Y, Mask);
3214 return new ShuffleVectorInst(
X, NewSel, Mask);
3219 return new ShuffleVectorInst(NewSel,
Y, Mask);
3231 auto *IDomNode = DT[BB]->getIDom();
3237 Value *IfTrue, *IfFalse;
3253 if (TrueSucc == FalseSucc)
3269 else if (DT.
dominates(FalseEdge, Incoming))
3294 CandidateBlocks.
insert(
I->getParent());
3297 if (
auto *PN = foldSelectToPhiImpl(Sel, BB, DT, Builder))
3310 Value *CondVal =
SI.getCondition();
3315 Value *
Op, *RemRes, *Remainder;
3317 bool TrueIfSigned =
false;
3331 return BinaryOperator::CreateAnd(
Op,
Add);
3343 return FoldToBitwiseAnd(Remainder);
3352 return FoldToBitwiseAnd(ConstantInt::get(RemRes->
getType(), 2));
3357Value *InstCombinerImpl::simplifyNestedSelectsUsingImpliedCond(
3359 Value *InnerCondVal =
SI.getCondition();
3360 Value *InnerTrueVal =
SI.getTrueValue();
3361 Value *InnerFalseVal =
SI.getFalseValue();
3363 "The type of inner condition must match with the outer.");
3365 return *Implied ? InnerTrueVal : InnerFalseVal;
3372 assert(
Op->getType()->isIntOrIntVectorTy(1) &&
3373 "Op must be either i1 or vector of i1.");
3374 if (
SI.getCondition()->getType() !=
Op->getType())
3376 if (
Value *
V = simplifyNestedSelectsUsingImpliedCond(SI,
Op, IsAnd))
3377 return createSelectInstWithUnknownProfile(
3387 Value *CondVal =
SI.getCondition();
3389 bool ChangedFMF =
false;
3390 for (
bool Swap : {
false,
true}) {
3429 if (FMF.
noNaNs() && !
SI.hasNoNaNs()) {
3430 SI.setHasNoNaNs(
true);
3433 if (FMF.
noInfs() && !
SI.hasNoInfs()) {
3434 SI.setHasNoInfs(
true);
3441 SI.setHasNoNaNs(
true);
3455 if (!
SI.hasNoSignedZeros() &&
3458 if (!
SI.hasNoNaNs() &&
3476 Instruction *NewFNeg = UnaryOperator::CreateFNeg(Fabs);
3485 for (
bool Swap : {
false,
true}) {
3508 if (
Swap != TrueIfSigned)
3513 return ChangedFMF ? &
SI :
nullptr;
3526foldSelectOfOrderedFAbsCmpOfNaNScrubbedValue(
SelectInst &
SI,
3541 Value *InnerSel =
SI.getTrueValue();
3546 if (!
match(InnerSel,
3553 auto MatchFAbsOfInnerSel = [&](
Value *
V) {
3558 if (!MatchFAbsOfInnerSel(Cmp0)) {
3559 if (!MatchFAbsOfInnerSel(Cmp1))
3590 uint64_t WeightNotNaN, WeightNaN, WeightComparisonTrue,
3591 WeightComparisonFalse = 0;
3593 WeightNotNaN, WeightNaN);
3597 return NewSelUsesReplaced;
3607 uint64_t WeightNewSelTrue = WeightNotNaN * WeightComparisonTrue;
3609 WeightNaN * (WeightComparisonTrue + WeightComparisonFalse) +
3610 WeightNotNaN * WeightComparisonFalse;
3613 {WeightNewSelTrue, WeightNewSelFalse},
3615 return NewSelUsesReplaced;
3637 Value *XBiasedHighBits =
SI.getFalseValue();
3650 const APInt *LowBitMaskCst;
3655 const APInt *BiasCst, *HighBitMaskCst;
3656 if (!
match(XBiasedHighBits,
3659 !
match(XBiasedHighBits,
3664 if (!LowBitMaskCst->
isMask())
3667 APInt InvertedLowBitMaskCst = ~*LowBitMaskCst;
3668 if (InvertedLowBitMaskCst != *HighBitMaskCst)
3671 APInt AlignmentCst = *LowBitMaskCst + 1;
3673 if (*BiasCst != AlignmentCst && *BiasCst != *LowBitMaskCst)
3678 if (*BiasCst == *LowBitMaskCst &&
impliesPoison(XBiasedHighBits,
X))
3679 return XBiasedHighBits;
3684 Type *Ty =
X->getType();
3685 Value *XOffset = Builder.
CreateAdd(
X, ConstantInt::get(Ty, *LowBitMaskCst),
3686 X->getName() +
".biased");
3687 Value *
R = Builder.
CreateAnd(XOffset, ConstantInt::get(Ty, *HighBitMaskCst));
3693struct DecomposedSelect {
3705foldSelectOfSymmetricSelect(
SelectInst &OuterSelVal,
3708 Value *OuterCond, *InnerCond, *InnerTrueVal, *InnerFalseVal;
3742 DecomposedSelect OuterSel;
3749 std::swap(OuterSel.TrueVal, OuterSel.FalseVal);
3757 Value *InnerSelVal = IsAndVariant ? OuterSel.FalseVal : OuterSel.TrueVal;
3765 DecomposedSelect InnerSel;
3766 if (!
match(InnerSelVal,
3772 bool SwapInnerSelCond =
false;
3774 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
3775 SwapInnerSelCond = !SwapInnerSelCond;
3778 Value *AltCond =
nullptr;
3779 auto matchOuterCond = [OuterSel, IsAndVariant, &AltCond](
auto m_InnerCond) {
3784 return IsAndVariant ?
match(OuterSel.Cond,
3794 if (matchOuterCond(
m_Specific(InnerSel.Cond))) {
3799 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
3800 InnerSel.Cond = NotInnerCond;
3801 SwapInnerSelCond = !SwapInnerSelCond;
3810 AltCond, IsAndVariant ? OuterSel.TrueVal : InnerSel.FalseVal,
3811 IsAndVariant ? InnerSel.TrueVal : OuterSel.FalseVal,
DEBUG_TYPE);
3814 InnerSel.Cond, IsAndVariant ? SelInner : InnerSel.TrueVal,
3815 !IsAndVariant ? SelInner : InnerSel.FalseVal,
"",
nullptr,
3817 if (SwapInnerSelCond)
3818 SI->swapProfMetadata();
3825static bool impliesPoisonOrCond(
const Value *ValAssumedPoison,
const Value *
V,
3837 if (ICmp->hasSameSign() &&
3860 .getMaxValue() == 1;
3867 Value *CondVal =
SI.getCondition();
3870 Type *SelType =
SI.getType();
3887 if (impliesPoisonOrCond(FalseVal, CondVal,
false,
SQ)) {
3889 return BinaryOperator::CreateOr(CondVal, FalseVal);
3893 impliesPoisonOrCond(FalseVal,
B,
false,
SQ)) {
3908 auto AndFactorization = [&](
Value *Common,
Value *InnerCond,
3910 bool SelFirst =
false) -> Instruction * {
3911 Value *InnerSel =
Builder.CreateSelectWithUnknownProfile(
3915 if (FalseLogicAnd || (CondLogicAnd && Common ==
A))
3916 return createSelectInstWithUnknownProfile(Common, InnerSel, Zero);
3918 return BinaryOperator::CreateAnd(Common, InnerSel);
3922 return AndFactorization(
A,
B,
D);
3924 return AndFactorization(
A,
B,
C);
3926 return AndFactorization(
B,
A,
D);
3928 return AndFactorization(
B,
A,
C, CondLogicAnd && FalseLogicAnd);
3933 if (impliesPoisonOrCond(TrueVal, CondVal,
true,
SQ)) {
3935 return BinaryOperator::CreateAnd(CondVal, TrueVal);
3939 impliesPoisonOrCond(TrueVal,
B,
true,
SQ)) {
3954 auto OrFactorization = [&](
Value *Common,
Value *InnerCond,
3956 bool SelFirst =
false) -> Instruction * {
3957 Value *InnerSel =
Builder.CreateSelectWithUnknownProfile(
3961 if (TrueLogicOr || (CondLogicOr && Common ==
A))
3962 return createSelectInstWithUnknownProfile(Common, One, InnerSel);
3964 return BinaryOperator::CreateOr(Common, InnerSel);
3968 return OrFactorization(
A,
B,
D);
3970 return OrFactorization(
A,
B,
C);
3972 return OrFactorization(
B,
A,
D);
3974 return OrFactorization(
B,
A,
C, CondLogicOr && TrueLogicOr);
4031 return BinaryOperator::CreateXor(
A,
B);
4040 return createSelectInstWithUnknownProfile(TrueVal, OrV, Zero);
4045 Value *OrV =
Builder.CreateSelectWithUnknownProfile(NotC, One, TrueVal,
4047 return createSelectInstWithUnknownProfile(FalseVal, OrV, Zero);
4055 Value *AndV =
Builder.CreateSelectWithUnknownProfile(NotC, FalseVal, Zero,
4057 return createSelectInstWithUnknownProfile(TrueVal, One, AndV);
4065 return createSelectInstWithUnknownProfile(FalseVal, One, AndV);
4073 auto *FI =
new FreezeInst(*
Y, (*Y)->getName() +
".fr");
4079 if (
auto *
V = foldBooleanAndOr(CondVal, Op1, SI, IsAnd,
4090 if (Res && *Res ==
false)
4096 if (Res && *Res ==
false)
4105 if (Res && *Res ==
true)
4111 if (Res && *Res ==
true)
4130 bool &ShouldDropNoWrap) {
4153 ShouldDropNoWrap =
false;
4159 auto MatchForward = [&](
Value *CommonAncestor) {
4160 const APInt *
C =
nullptr;
4161 if (CtlzOp == CommonAncestor)
4164 ShouldDropNoWrap =
true;
4169 ShouldDropNoWrap =
true;
4180 const APInt *
C =
nullptr;
4181 Value *CommonAncestor;
4182 if (MatchForward(Cond0)) {
4186 if (!MatchForward(CommonAncestor))
4224 Type *SelType =
SI.getType();
4233 Value *Cond0, *Ctlz, *CtlzOp;
4242 bool ShouldDropNoWrap;
4249 !isSafeToRemoveBitCeilSelect(
Pred, Cond0, Cond1, CtlzOp,
BitWidth,
4253 if (ShouldDropNoWrap) {
4285 Value *TV =
SI.getTrueValue();
4286 Value *FV =
SI.getFalseValue();
4307 auto FlippedPredAndConst =
4309 if (!FlippedPredAndConst)
4311 Pred = FlippedPredAndConst->first;
4312 RHS = FlippedPredAndConst->second;
4330 CmpPredicate ExtendedCmpPredicate;
4350 CmpPredicate FalseBranchSelectPredicate;
4351 const APInt *InnerTV, *InnerFV;
4357 FalseBranchSelectPredicate =
4362 if (!InnerTV->
isOne()) {
4378 CmpPredicate InnerPred;
4380 const APInt *InnerTV, *InnerFV;
4389 bool CanSubOne = IsSigned ? !
C->isMinSignedValue() : !
C->isMinValue();
4391 APInt Cminus1 = *
C - 1;
4401 bool CanAddOne = IsSigned ? !
C->isMaxSignedValue() : !
C->isMaxValue();
4403 APInt Cplus1 = *
C + 1;
4412 Intrinsic::ID IID = IsSigned ? Intrinsic::scmp : Intrinsic::ucmp;
4415 SI,
Builder.CreateIntrinsic(
SI.getType(), IID, {LHS, RHS}));
4421 KnownFPClass
Known =
4424 return Known.isKnownNeverNaN() &&
Known.isKnownNeverInfinity() &&
4464 return Op->getType()->isIntOrIntVectorTy() &&
4465 hasAffectedValue(Op, Affected, Depth + 1);
4479 if (!SIFOp || !SIFOp->hasNoSignedZeros() || !SIFOp->hasNoNaNs())
4482 auto TryFoldIntoAddConstant =
4494 Swapped ?
X : Z,
"", &
SI);
4525 return TryFoldIntoAddConstant(
Pred,
X, Z,
FAdd,
C,
false);
4529 return TryFoldIntoAddConstant(
Pred,
X, Z,
FAdd,
C,
true);
4545 bool CreateAnd =
false;
4547 Value *CmpLHS, *CmpRHS;
4555 const APInt *AndRHS;
4562 AndMask = Res->Mask;
4565 AndMask &=
Known.getMaxValue();
4575 V = Trunc->getOperand(0);
4576 AndMask =
APInt(
V->getType()->getScalarSizeInBits(), 1);
4578 CreateAnd = !Trunc->hasNoUnsignedWrap();
4587 CreateAnd, Builder))
4591 CreateAnd, Builder))
4604 auto *CondVal =
SI.getCondition();
4607 auto *SelTy =
SI.getType();
4609 if (!SelTy->isIntOrIntVectorTy() || SelTy->isIntOrIntVectorTy(1))
4624 if (matchNegNot(TrueVal, FalseVal,
X)) {
4627 return BinaryOperator::CreateSub(Mask,
X);
4631 if (matchNegNot(FalseVal, TrueVal,
X)) {
4633 return BinaryOperator::CreateSub(Mask,
X);
4646 if (!
Cond->hasOneUse())
4675 return BinaryOperator::CreateAnd(And1,
B);
4683static bool isSelectZeroSignInsignificant(
SelectInst &
SI) {
4686 constexpr unsigned MaxUsesToLookThrough = 16;
4687 unsigned NumUses = 0;
4690 while (!Worklist.empty()) {
4691 for (
Use &U : Worklist.pop_back_val()->
uses()) {
4692 if (++NumUses > MaxUsesToLookThrough)
4701 Worklist.push_back(
User);
4711 Value *CondVal =
SI.getCondition();
4714 Type *SelType =
SI.getType();
4718 FMF = FPMO->getFastMathFlags();
4721 SQ.getWithInstruction(&SI)))
4724 if (Instruction *
I = canonicalizeSelectToShuffle(SI))
4727 if (Instruction *
I = canonicalizeScalarSelectOfVecs(SI, *
this))
4779 return new ZExtInst(CondVal, SelType);
4783 return new SExtInst(CondVal, SelType);
4788 return new ZExtInst(NotCond, SelType);
4794 return new SExtInst(NotCond, SelType);
4798 if (Instruction *
I = foldSelectNegNot(SI,
Builder))
4801 if (Instruction *
I = foldSelectAndOrPowerOfTwo(SI,
Builder,
SQ))
4808 Value *Cmp0 = FCmp->getOperand(0), *Cmp1 = FCmp->getOperand(1);
4810 if ((Cmp0 == TrueVal && Cmp1 == FalseVal) ||
4811 (Cmp0 == FalseVal && Cmp1 == TrueVal)) {
4819 Value *NewCond =
Builder.CreateFCmpFMF(InvPred, Cmp0, Cmp1, FCmp,
4820 FCmp->getName() +
".inv");
4822 FastMathFlags FMF =
SI.getFastMathFlags();
4823 if (FCmp->hasNoNaNs())
4825 if (FCmp->hasNoInfs())
4828 NewCond, FalseVal, TrueVal, FMF,
"",
4850 Value *MatchCmp0 =
nullptr;
4851 Value *MatchCmp1 =
nullptr;
4863 if (Cmp0 == MatchCmp0 &&
4864 matchFMulByZeroIfResultEqZero(*
this, Cmp0, Cmp1, MatchCmp1, MatchCmp0,
4865 SI, SIFPOp->hasNoSignedZeros()))
4905 bool CanonicalizeIfNotNan =
4908 if (RcpIfNan || CanonicalizeIfNotNan) {
4910 DenormalMode
Mode =
F.getDenormalMode(FPSem);
4916 if (CanonicalizeIfNotNan)
4930 new FreezeInst(Cmp0, Cmp0->
getName() +
".fr"),
4931 FCmp->getIterator());
4939 if (CanonicalizeIfNotNan) {
4960 if (RcpIfNan && (
Mode.inputsAreZero() ||
Mode.outputsAreZero()))
4989 if (FCmp && FCmp->hasNoNaNs() &&
4990 (SIFPOp->hasNoSignedZeros() || isSelectZeroSignInsignificant(SI))) {
4994 Builder.CreateBinaryIntrinsic(Intrinsic::maxnum,
X,
Y, &SI);
4998 BinIntrInst->setHasNoInfs(FCmp->hasNoInfs());
5003 BinIntrInst->setHasNoSignedZeros(
true);
5006 BinIntrInst->setHasNoNaNs(
true);
5013 Builder.CreateBinaryIntrinsic(Intrinsic::minnum,
X,
Y, &SI);
5015 BinIntrInst->setHasNoInfs(FCmp->hasNoInfs());
5016 BinIntrInst->setHasNoSignedZeros(
true);
5017 BinIntrInst->setHasNoNaNs(
true);
5025 if (Instruction *Fabs = foldSelectWithFCmpToFabs(SI, *
this))
5028 if (Instruction *
I = foldSelectOfOrderedFAbsCmpOfNaNScrubbedValue(SI, *
this))
5040 if (Instruction *
V =
5044 if (
Value *
V = foldSelectBitTest(SI, CondVal, TrueVal, FalseVal,
Builder,
SQ))
5047 if (Instruction *
Add = foldAddSubSelect(SI,
Builder))
5049 if (Instruction *
Add = foldOverflowingAddSubSelect(SI,
Builder))
5059 if (TI && FI && TI->getOpcode() == FI->getOpcode())
5069 if (Instruction *
I = foldSelectWithSRem(SI, *
this,
Builder))
5074 auto SelectGepWithBase = [&](GetElementPtrInst *Gep,
Value *
Base,
5075 bool Swap) -> GetElementPtrInst * {
5089 Builder.CreateSelect(CondVal, NewT, NewF,
SI.getName() +
".idx", &SI);
5094 if (
auto *NewGep = SelectGepWithBase(TrueGep, FalseVal,
false))
5097 if (
auto *NewGep = SelectGepWithBase(FalseGep, TrueVal,
true))
5113 RHS2, SI, SPF,
RHS))
5117 RHS2, SI, SPF,
LHS))
5126 bool IsCastNeeded =
LHS->
getType() != SelType;
5131 ((CmpLHS !=
LHS && CmpLHS !=
RHS) ||
5132 (CmpRHS !=
LHS && CmpRHS !=
RHS)))) {
5137 dropPoisonGeneratingAnnotationsForSPFCanonicalization(CondVal,
LHS,
5148 Value *NewCast =
Builder.CreateCast(CastOp, NewSI, SelType);
5160 if (TrueSI->getCondition()->getType() == CondVal->
getType()) {
5163 if (
Value *
V = simplifyNestedSelectsUsingImpliedCond(*TrueSI, CondVal,
5170 if (TrueSI->hasOneUse()) {
5171 Value *
And =
nullptr, *OtherVal =
nullptr;
5173 if (TrueSI->getFalseValue() == FalseVal) {
5174 And =
Builder.CreateLogicalAnd(CondVal, TrueSI->getCondition(),
"",
5176 OtherVal = TrueSI->getTrueValue();
5179 else if (TrueSI->getTrueValue() == FalseVal) {
5180 Value *InvertedCond =
Builder.CreateNot(TrueSI->getCondition());
5181 And =
Builder.CreateLogicalAnd(CondVal, InvertedCond,
"", &SI);
5182 OtherVal = TrueSI->getFalseValue();
5184 if (
And && OtherVal) {
5194 if (FalseSI->getCondition()->getType() == CondVal->
getType()) {
5197 if (
Value *
V = simplifyNestedSelectsUsingImpliedCond(
5198 *FalseSI, CondVal,
false))
5201 if (FalseSI->hasOneUse()) {
5202 Value *
Or =
nullptr, *OtherVal =
nullptr;
5204 if (FalseSI->getTrueValue() == TrueVal) {
5205 Or =
Builder.CreateLogicalOr(CondVal, FalseSI->getCondition(),
"",
5207 OtherVal = FalseSI->getFalseValue();
5210 else if (FalseSI->getFalseValue() == TrueVal) {
5211 Value *InvertedCond =
Builder.CreateNot(FalseSI->getCondition());
5212 Or =
Builder.CreateLogicalOr(CondVal, InvertedCond,
"", &SI);
5213 OtherVal = FalseSI->getTrueValue();
5215 if (
Or && OtherVal) {
5231 BinaryOperator *TrueBO;
5234 if (TrueBOSI->getCondition() == CondVal) {
5241 if (TrueBOSI->getCondition() == CondVal) {
5250 BinaryOperator *FalseBO;
5253 if (FalseBOSI->getCondition() == CondVal) {
5260 if (FalseBOSI->getCondition() == CondVal) {
5273 SI.swapProfMetadata();
5288 if (
Known.One.isOne())
5290 if (
Known.Zero.isOne())
5294 if (Instruction *BitCastSel = foldSelectCmpBitcasts(SI,
Builder))
5298 if (
Value *
V = foldSelectCmpXchg(SI))
5304 if (Instruction *Funnel = foldSelectFunnelShift(SI,
Builder))
5307 if (Instruction *Copysign = foldSelectToCopysign(SI,
Builder))
5310 if (Instruction *PN = foldSelectToPhi(SI,
DT,
Builder))
5313 if (
Value *
V = foldRoundUpIntegerWithPow2Alignment(SI,
Builder))
5328 MaskedInst->setArgOperand(2, FalseVal );
5343 bool CanMergeSelectIntoLoad =
false;
5347 if (CanMergeSelectIntoLoad) {
5350 MaskedInst->setArgOperand(2, TrueVal );
5355 if (Instruction *
I = foldSelectOfSymmetricSelect(SI,
Builder))
5358 if (Instruction *
I = foldNestedSelects(SI,
Builder))
5368 if (Instruction *
I = foldBitCeil(SI,
Builder, *
this))
5382 auto FoldSelectWithAndOrCond = [&](
bool IsAnd,
Value *
A,
5383 Value *
B) -> Instruction * {
5389 if (NestedSI->getCondition() ==
A)
5393 SQ.getWithInstruction(&SI))) {
5395 A, IsAnd ?
V : TrueVal, IsAnd ? FalseVal :
V,
"",
nullptr,
5405 if (
Value *
V = canonicalizeSPF(*Cmp, TrueVal, FalseVal, *
this)) {
5407 A, IsAnd ?
V : TrueVal, IsAnd ? FalseVal :
V,
"",
nullptr,
5420 if (Instruction *
I = FoldSelectWithAndOrCond(
true,
LHS,
RHS))
5422 if (Instruction *
I = FoldSelectWithAndOrCond(
true,
RHS,
LHS))
5425 if (Instruction *
I = FoldSelectWithAndOrCond(
false,
LHS,
RHS))
5427 if (Instruction *
I = FoldSelectWithAndOrCond(
false,
RHS,
LHS))
5433 if (Instruction *
I = FoldSelectWithAndOrCond(
true,
LHS,
RHS))
5436 if (Instruction *
I = FoldSelectWithAndOrCond(
false,
LHS,
RHS))
5443 return BinaryOperator::CreateXor(CondVal, FalseVal);
5450 CondContext
CC(CondVal);
5452 CC.AffectedValues.insert(
V);
5454 SimplifyQuery Q =
SQ.getWithInstruction(&SI).getWithCondContext(
CC);
5455 if (!
CC.AffectedValues.empty()) {
5457 hasAffectedValue(TrueVal,
CC.AffectedValues, 0)) {
5459 if (
Known.isConstant())
5461 ConstantInt::get(SelType,
Known.getConstant()));
5466 hasAffectedValue(FalseVal,
CC.AffectedValues, 0)) {
5468 if (
Known.isConstant())
5470 ConstantInt::get(SelType,
Known.getConstant()));
5481 if (TrueVal == Trunc)
5483 if (FalseVal == Trunc)
5487 if (TrueVal == Trunc)
5490 if (FalseVal == Trunc)
5497 .countMaxActiveBits() == 1)
5498 return BinaryOperator::CreateAnd(Trunc, TrueVal);
5503 .countMaxActiveBits() == 1) {
5504 return BinaryOperator::CreateOr(Trunc, FalseVal);
5508 Value *MaskedLoadPtr;
5514 if (
DT.dominates(FalseVal, LoadInst)) {
5515 Builder.SetInsertPoint(LoadInst);
5517 TrueVal->getType(), MaskedLoadPtr,
5518 LoadInst->getParamAlign(0).valueOrOne(), CondVal, FalseVal);
5519 In->setAAMetadata(LoadInst->getAAMetadata());
5527 unsigned BitWidth =
SI.getType()->getScalarSizeInBits();
5529 Value *CmpLHS, *CmpRHS;
5546 SI.getModule(), Intrinsic::scmp, {SI.getType(), SI.getType()});
const TargetLowering & TLI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const HexagonInstrInfo * TII
This file provides internal interfaces used to implement the InstCombine.
static Value * foldSelectICmpMinMax(const ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder, const SimplifyQuery &SQ)
Try to fold a select to a min/max intrinsic.
static Instruction * foldSelectIntoIntrinsicArg(SelectInst &SI, IntrinsicInst *TII, IntrinsicInst *FII, InstCombiner::BuilderTy &Builder)
select C, f(..., X, ...), f(..., Y, ...) --> f(..., select C, X, Y, ...)
static Value * canonicalizeSaturatedAddSigned(ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
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 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 Value * canonicalizeSaturatedSubtract(const ICmpInst *ICI, const Value *TrueVal, const Value *FalseVal, InstCombiner::BuilderTy &Builder)
static Value * canoncalizeSelectICmpMinMax(const ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder, const SimplifyQuery &SQ)
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 * foldSelectZeroOrFixedOp(SelectInst &SI, InstCombinerImpl &IC)
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 * foldSelectICmpAnd(SelectInst &Sel, Value *CondVal, Value *TrueVal, Value *FalseVal, Value *V, const APInt &AndMask, bool CreateAnd, 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...
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 * canonicalizeSaturatedSubtractSigned(const ICmpInst *ICI, const Value *TrueVal, const Value *FalseVal, InstCombiner::BuilderTy &Builder)
static Value * canonicalizeSaturatedAddUnsigned(ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
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 Instruction * foldSelectICmpAndAnd(Type *SelType, const Value *Cond, 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 Value * canonicalizeSaturatedSubtractUnsigned(const ICmpInst *ICI, const Value *TrueVal, const Value *FalseVal, InstCombiner::BuilderTy &Builder)
Transform patterns such as (a > b) ?
static Value * foldSelectICmpAndBinOp(Value *CondVal, Value *TrueVal, Value *FalseVal, Value *V, const APInt &AndMask, bool CreateAnd, 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,...
This file provides the interface for the instcombine pass implementation.
static bool hasNoSignedWrap(BinaryOperator &I)
static bool hasNoUnsignedWrap(BinaryOperator &I)
uint64_t IntrinsicInst * II
This file contains the declarations for profiling metadata utility functions.
MachineBasicBlock * Folded
SmallVector< MachineOperand, 4 > Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This file defines the SmallVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
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 isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isSignMask() const
Check if the APInt's value is returned by getSignMask.
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 isNonNegative() const
Determine if this APInt Value is non-negative (>= 0)
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
bool isSignBitSet() const
Determine if sign bit of this APInt is set.
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.
bool isMaxValue() const
Determine if this is the largest unsigned value.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
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; assumes that the block is well-formed.
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
This class represents a no-op cast from one type to another.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Value * getArgOperand(unsigned i) const
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
This class is the base class for the comparison instructions.
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
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ 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
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
static bool isFPPredicate(Predicate P)
bool isNonStrictPredicate() const
static bool isRelational(Predicate P)
Return true if the predicate is relational (not EQ or NE).
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 LLVM_ABI 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 LLVM_ABI bool isOrdered(Predicate predicate)
Determine if the predicate is an ordered operation.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
static LLVM_ABI std::optional< CmpPredicate > getMatching(CmpPredicate A, CmpPredicate B)
Compares two CmpPredicates taking samesign into account and returns the canonicalized CmpPredicate if...
static LLVM_ABI Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)
Return the identity constant for a binary opcode.
static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
This class represents a range of values.
LLVM_ABI ConstantRange add(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an addition of a value in this ran...
LLVM_ABI bool icmp(CmpInst::Predicate Pred, const ConstantRange &Other) const
Does the predicate Pred hold between ranges this and Other?
static LLVM_ABI ConstantRange intrinsic(Intrinsic::ID IntrinsicID, ArrayRef< ConstantRange > Ops)
Compute range of intrinsic result for the given operand ranges.
static LLVM_ABI 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...
LLVM_ABI ConstantRange binaryNot() const
Return a new range representing the possible values resulting from a binary-xor of a value in this ra...
LLVM_ABI 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...
LLVM_ABI 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 LLVM_ABI Constant * mergeUndefsWith(Constant *C, Constant *Other)
Merges undefs of a Constant with another Constant, along with the undefs already present.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
LLVM_ABI bool isOneValue() const
Returns true if the value is one.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
A parsed version of the target data layout string in and methods for querying it.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Tagged union holding either a T or a Error.
This provides a helper for copying FMF from an instruction or setting specified flags.
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.
static FastMathFlags intersectRewrite(FastMathFlags LHS, FastMathFlags RHS)
Intersect rewrite-based flags.
bool noSignedZeros() const
static FastMathFlags unionValue(FastMathFlags LHS, FastMathFlags RHS)
Union value flags.
void setNoSignedZeros(bool B=true)
void setNoNaNs(bool B=true)
void setNoInfs(bool B=true)
This class represents a freeze function that returns random concrete value if an operand is either a ...
Value * getPointerOperand()
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Type * getSourceElementType() const
LLVM_ABI GEPNoWrapFlags getNoWrapFlags() const
Get the nowrap flags for the GEP instruction.
This instruction compares its operands according to the predicate given to the constructor.
static CmpPredicate getSwappedCmpPredicate(CmpPredicate Pred)
static bool isLT(Predicate P)
Return true if the predicate is SLT or ULT.
CmpPredicate getInverseCmpPredicate() const
static bool isGT(Predicate P)
Return true if the predicate is SGT or UGT.
static CmpPredicate getInverseCmpPredicate(CmpPredicate Pred)
static bool isEquality(Predicate P)
Return true if this predicate is either EQ or NE.
bool isRelational() const
Return true if the predicate is relational (not EQ or NE).
Common base class shared among various IRBuilders.
Value * CreateFAdd(Value *L, Value *R, const Twine &Name="", MDNode *FPMD=nullptr)
LLVM_ABI Value * CreateSelectFMF(Value *C, Value *True, Value *False, FMFSource FMFSource, const Twine &Name="", Instruction *MDFrom=nullptr)
LLVM_ABI Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")
Return a vector value that contains.
Value * CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateFreeze(Value *V, const Twine &Name="")
Value * CreateFAbs(Value *V, FMFSource FMFSource={}, const Twine &Name="")
Create call to the fabs intrinsic.
Value * CreateFCmpFMF(CmpInst::Predicate P, Value *LHS, Value *RHS, FMFSource FMFSource, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
LLVM_ABI Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 2 operands which is mangled on the first type.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI Value * CreateSelectWithUnknownProfile(Value *C, Value *True, Value *False, StringRef PassName, const Twine &Name="")
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
ConstantInt * getFalse()
Get the constant value for i1 false.
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateFNeg(Value *V, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Instruction * foldSelectToCmp(SelectInst &SI)
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).
Instruction * foldSelectEqualityTest(SelectInst &SI)
Instruction * foldSelectValueEquivalence(SelectInst &SI, CmpInst &CI)
Instruction * foldOpIntoPhi(Instruction &I, PHINode *PN, bool AllowMultipleUses=false)
Given a binary operator, cast instruction, or select which has a PHI node as operand #0,...
Instruction * foldVectorSelect(SelectInst &Sel)
Value * SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, APInt &PoisonElts, unsigned Depth=0, bool AllowMultipleUsers=false) override
The specified value produces a vector with any number of elements.
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 * foldSelectIntrinsic(SelectInst &SI)
This transforms patterns of the form: select cond, intrinsic(x, ...), intrinsic(y,...
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 * FoldOrOfLogicalAnds(Value *Op0, Value *Op1)
Value * foldSelectWithConstOpToBinOp(ICmpInst *Cmp, Value *TrueVal, Value *FalseVal)
Instruction * visitSelectInst(SelectInst &SI)
Instruction * foldSelectOfBools(SelectInst &SI)
Instruction * foldSelectExtConst(SelectInst &Sel)
The core instruction combiner logic.
const DataLayout & getDataLayout() const
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, const Instruction *CtxI=nullptr, unsigned Depth=0)
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)
void replaceUse(Use &U, Value *NewValue)
Replace use and add the previously used value to the worklist.
static bool isCanonicalPredicate(CmpPredicate Pred)
Predicate canonicalization reduces the number of patterns that need to be matched by other transforms...
InstructionWorklist & Worklist
A worklist of the instructions that need to be simplified.
IRBuilder< TargetFolder, IRBuilderInstCombineInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
void addToWorklist(Instruction *I)
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
void computeKnownBits(const Value *V, KnownBits &Known, const Instruction *CtxI, unsigned Depth=0) const
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
const SimplifyQuery & getSimplifyQuery() const
static Constant * AddOne(Constant *C)
Add one to a Constant.
LLVM_ABI bool hasNoNaNs() const LLVM_READONLY
Determine whether the no-NaNs flag is set.
LLVM_ABI bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
LLVM_ABI bool hasNoInfs() const LLVM_READONLY
Determine whether the no-infs flag is set.
LLVM_ABI 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.
LLVM_ABI void setHasNoSignedZeros(bool B)
Set or clear the no-signed-zeros flag on this instruction, which must be an operator which supports t...
LLVM_ABI bool hasNoSignedZeros() const LLVM_READONLY
Determine whether the no-signed-zeros flag is set.
LLVM_ABI bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
LLVM_ABI void copyIRFlags(const Value *V, bool IncludeWrapFlags=true)
Convenience method to copy supported exact, fast-math, and (optionally) wrapping flags from V to this...
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
LLVM_ABI void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction.
LLVM_ABI void setHasNoNaNs(bool B)
Set or clear the no-nans flag on this instruction, which must be an operator which supports this flag...
LLVM_ABI bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
LLVM_ABI void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI void swapProfMetadata()
If the instruction has "branch_weights" MD_prof metadata and the MDNode has three operands (including...
LLVM_ABI void setHasNoInfs(bool B)
Set or clear the no-infs flag on this instruction, which must be an operator which supports this flag...
LLVM_ABI 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.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
A wrapper class for inspecting calls to intrinsic functions.
bool isKnownNeverNaN() const
Return true if it's known this can never be a nan.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
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
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
const Value * getTrueValue() const
bool insert(const value_type &X)
Insert a new element into the SetVector.
This instruction constructs a fixed permutation of two input vectors.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
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.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
bool isIEEELikeFPTy() const
Return true if this is a well-behaved IEEE-like type, which has a IEEE compatible layout,...
LLVM_ABI const fltSemantics & getFltSemantics() const
static UnaryOperator * CreateFNegFMF(Value *Op, Instruction *FMFSource, const Twine &Name="", InsertPosition InsertBefore=nullptr)
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI 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.
iterator_range< use_iterator > uses()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI 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.
const ParentTy * getParent() const
self_iterator getIterator()
#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.
int getMinValue(MCInstrInfo const &MCII, MCInst const &MCI)
Return the minimum value of an extendable operand.
int getMaxValue(MCInstrInfo const &MCII, MCInst const &MCI)
Return the maximum value of an extendable operand.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
BinaryOpc_match< LHS, RHS, false > m_BinOp(unsigned Opcode, const LHS &L, const RHS &R)
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
auto m_PosZeroFP()
Matches a floating-point positive zero.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
AllOnesConstantMatch m_AllOnes()
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
match_combine_and< Ty... > m_CombineAnd(const Ty &...Ps)
Combine pattern matchers matching all of Ps patterns.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
cst_pred_ty< is_negative > m_Negative()
Match an integer or vector of negative values.
auto m_Cmp()
Matches any compare instruction and ignore it.
BinaryOp_match< cst_pred_ty< is_all_ones, false >, ValTy, Instruction::Xor, true > m_NotForbidPoison(const ValTy &V)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, FCmpInst > m_FCmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FMul, true > m_c_FMul(const LHS &L, const RHS &R)
Matches FMul with LHS and RHS in either order.
cst_pred_ty< is_sign_mask > m_SignMask()
Match an integer or vector with only the sign bit(s) set.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
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.
match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)
CommutativeBinaryIntrinsic_match< IntrID, T0, T1 > m_c_Intrinsic(const T0 &Op0, const T1 &Op1)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
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.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
LogicalOp_match< LHS, RHS, Instruction::And > m_LogicalAnd(const LHS &L, const RHS &R)
Matches L && R either in the form of L & R or L ?
auto m_ConstantExpr()
Match a constant expression or a constant that contains a constant expression.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWSub(const LHS &L, const RHS &R)
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
match_combine_or< CastInst_match< OpTy, ZExtInst >, OpTy > m_ZExtOrSelf(const OpTy &Op)
bool match(Val *V, const Pattern &P)
BinOpPred_match< LHS, RHS, is_idiv_op > m_IDiv(const LHS &L, const RHS &R)
Matches integer division operations.
match_bind< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
match_deferred< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
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.
specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)
ap_match< APFloat > m_APFloatAllowPoison(const APFloat *&Res)
Match APFloat while allowing poison in splat vector constants.
CmpClass_match< LHS, RHS, ICmpInst, true > m_c_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
auto match_fn(const Pattern &P)
A match functor that can be used as a UnaryPredicate in functional algorithms like all_of.
OverflowingBinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWNeg(const ValTy &V)
Matches a 'Neg' as 'sub nsw 0, V'.
TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)
Matches ExtractElementInst.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
auto m_BinOp()
Match an arbitrary binary operation and ignore it.
auto m_BasicBlock()
Match an arbitrary basic block value and ignore it.
ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)
Match a single index ExtractValue instruction.
BinOpPred_match< LHS, RHS, is_logical_shift_op > m_LogicalShift(const LHS &L, const RHS &R)
Matches logical shift operations.
cst_pred_ty< is_any_apint > m_AnyIntegralConstant()
Match an integer or vector with any integral constant.
auto m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Xor, true > m_c_Xor(const LHS &L, const RHS &R)
Matches an Xor with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::FAdd > m_FAdd(const LHS &L, const RHS &R)
auto m_Ctpop(const Opnd0 &Op0)
auto m_Constant()
Match an arbitrary Constant and ignore it.
NoWrapTrunc_match< OpTy, TruncInst::NoSignedWrap > m_NSWTrunc(const OpTy &Op)
Matches trunc nsw.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
ap_match< APInt > m_APIntForbidPoison(const APInt *&Res)
Match APInt while forbidding poison in splat vector constants.
cst_pred_ty< is_strictlypositive > m_StrictlyPositive()
Match an integer or vector of strictly positive values.
auto m_MaskedGather(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
Matches MaskedGather Intrinsic.
match_bind< WithOverflowInst > m_WithOverflowInst(WithOverflowInst *&I)
Match a with overflow intrinsic, capturing it if we match.
SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
auto m_Ctlz(const Opnd0 &Op0, const Opnd1 &Op1)
match_combine_or< FMaxMin_match< LHS, RHS, ofmin_pred_ty >, FMaxMin_match< LHS, RHS, ufmin_pred_ty > > m_OrdOrUnordFMin(const LHS &L, const RHS &R)
Match an 'ordered' or 'unordered' floating point minimum function.
auto m_FCanonicalize(const Opnd0 &Op0)
is_zero< true > m_Zero()
Match any null constant or a vector with all elements equal to 0.
auto m_FShl(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
cst_pred_ty< icmp_pred_with_threshold, false > m_SpecificInt_ICMP_ForbidPoison(ICmpInst::Predicate Predicate, const APInt &Threshold)
Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
auto m_c_LogicalOp(const LHS &L, const RHS &R)
Matches either L && R or L || R with LHS and RHS in either order.
NoWrapTrunc_match< OpTy, TruncInst::NoUnsignedWrap > m_NUWTrunc(const OpTy &Op)
Matches trunc nuw.
SelectLike_match< CondTy, LTy, RTy > m_SelectLike(const CondTy &C, const LTy &TrueC, const RTy &FalseC)
Matches a value that behaves like a boolean-controlled select, i.e.
specific_fpval m_FPOne()
Match a float 1.0 or vector with all elements equal to 1.0.
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
SpecificCmpClass_match< LHS, RHS, FCmpInst > m_SpecificFCmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
auto m_MaskedLoad(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
Matches MaskedLoad Intrinsic.
FNeg_match< OpTy, true > m_FNegOrFSubNegZero(const OpTy &X)
Match fneg X or fsub -0.0, X.
cst_pred_ty< is_maxsignedvalue > m_MaxSignedValue()
Match an integer or vector with values having all bits except for the high bit set (0x7f....
auto m_FAbs(const Opnd0 &Op0)
AnyBinaryOp_match< LHS, RHS, true > m_c_BinOp(const LHS &L, const RHS &R)
Matches a BinaryOperator with LHS and RHS in either order.
match_combine_or< FMaxMin_match< LHS, RHS, ofmax_pred_ty >, FMaxMin_match< LHS, RHS, ufmax_pred_ty > > m_OrdOrUnordFMax(const LHS &L, const RHS &R)
Match an 'ordered' or 'unordered' floating point maximum function.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap > m_NSWAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
LogicalOp_match< LHS, RHS, Instruction::And, true > m_c_LogicalAnd(const LHS &L, const RHS &R)
Matches L && R with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FDiv > m_FDiv(const LHS &L, const RHS &R)
BinOpPred_match< LHS, RHS, is_irem_op > m_IRem(const LHS &L, const RHS &R)
Matches integer remainder operations.
auto m_MaxOrMin(const Opnd0 &Op0, const Opnd1 &Op1)
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
brc_match< Cond_t, match_bind< BasicBlock >, match_bind< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)
auto m_Undef()
Match an arbitrary undef constant.
auto m_VecReverse(const Opnd0 &Op0)
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
LogicalOp_match< LHS, RHS, Instruction::Or, true > m_c_LogicalOr(const LHS &L, const RHS &R)
Matches L || R with LHS and RHS in either order.
SpecificCmpClass_match< LHS, RHS, ICmpInst, true > m_c_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
ElementWiseBitCast_match< OpTy > m_ElementWiseBitCast(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
auto m_Cttz(const Opnd0 &Op0, const Opnd1 &Op1)
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
auto m_FShr(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
cst_pred_ty< icmp_pred_with_threshold > m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold)
Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
Not(const Pred &P) -> Not< Pred >
ElementType
The element type of an SRV or UAV resource.
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< UseNode * > Use
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, const SimplifyQuery &SQ, unsigned Depth=0)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
LLVM_ABI cl::opt< bool > ProfcheckDisableMetadataFixes
LLVM_ABI 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.
@ Known
Known to have no common set bits.
LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I, StringRef PassName, const Function *F=nullptr)
Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch weights in the new instruct...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
APFloat abs(APFloat X)
Returns the absolute value of the argument.
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
LLVM_ABI CmpInst::Predicate getMinMaxPred(SelectPatternFlavor SPF, bool Ordered=false)
Return the canonical comparison predicate for the specified minimum/maximum flavor.
LLVM_ABI bool canIgnoreSignBitOfZero(const Use &U)
Return true if the sign bit of the FP value can be ignored by the user when the value is zero.
LLVM_ABI bool isGuaranteedNotToBeUndef(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be undef, but may be poison.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI Constant * ConstantFoldIntrinsic(Intrinsic::ID ID, ArrayRef< Constant * > Ops, Type *Ty, const DataLayout &DL, const Function *CtxF=nullptr)
LLVM_ABI bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Return true if the given value is known to have exactly one bit set when defined.
LLVM_ABI Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Function *CtxF=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)
Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...
constexpr unsigned MaxAnalysisRecursionDepth
SelectPatternFlavor
Specific patterns of select instructions we can match.
@ SPF_ABS
Floating point maxnum.
@ SPF_NABS
Absolute value.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI bool canReplacePointersIfEqual(const Value *From, const Value *To, const DataLayout &DL)
Returns true if a pointer value From can be replaced with another pointer value \To if they are deeme...
LLVM_ABI bool impliesPoison(const Value *ValAssumedPoison, const Value *V)
Return true if V is poison given that ValAssumedPoison is already poison.
LLVM_ABI SelectPatternResult getSelectPattern(CmpInst::Predicate Pred, SelectPatternNaNBehavior NaNBehavior=SPNB_NA, bool Ordered=false)
Determine the pattern for predicate X Pred Y ? X : Y.
LLVM_ABI bool cannotBeNegativeZero(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if we can prove that the specified FP value is never equal to -0.0.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Value * simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, FastMathFlags FMF, const SimplifyQuery &Q)
Given operands for a SelectInst, fold the result or return null.
LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
LLVM_ABI Value * simplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an And, fold the result or return null.
LLVM_ABI bool isKnownInversion(const Value *X, const Value *Y)
Return true iff:
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI bool isNotCrossLaneOperation(const Instruction *I)
Return true if the instruction doesn't potentially cross vector lanes.
LLVM_ABI Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
constexpr int PoisonMaskElem
LLVM_ABI Intrinsic::ID getMinMaxIntrinsic(SelectPatternFlavor SPF)
Convert given SPF to equivalent min/max intrinsic.
LLVM_ABI SelectPatternResult matchDecomposedSelectPattern(CmpInst *CmpI, Value *TrueVal, Value *FalseVal, Value *&LHS, Value *&RHS, FastMathFlags FMF=FastMathFlags(), Instruction::CastOps *CastOp=nullptr)
Determine the pattern that a select with the given compare as its predicate and given values as its t...
@ Or
Bitwise or logical OR of integers.
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
@ SMin
Signed integer min implemented in terms of select(cmp()).
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
LLVM_ABI bool canReplaceOperandWithVariable(const Instruction *I, unsigned OpIdx)
Given an instruction, is it legal to set operand OpIdx to a non-constant value?
DWARFExpression::Operation Op
bool isSafeToSpeculativelyExecuteWithVariableReplaced(const Instruction *I, bool IgnoreUBImplyingAttrs=true)
Don't use information from its non-constant operands.
constexpr unsigned BitWidth
LLVM_ABI Constant * getLosslessInvCast(Constant *C, Type *InvCastTo, unsigned CastOp, const DataLayout &DL, PreservedCastFlags *Flags=nullptr)
Try to cast C to InvC losslessly, satisfying CastOp(InvC) equals C, or CastOp(InvC) is a refined valu...
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
LLVM_ABI Value * simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp, const SimplifyQuery &Q, bool AllowRefinement, SmallVectorImpl< Instruction * > *DropFlags=nullptr)
See if V simplifies when its operand Op is replaced with RepOp.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isKnownNeverNaN(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...
auto predecessors(const MachineBasicBlock *BB)
LLVM_ABI std::optional< std::pair< CmpPredicate, Constant * > > getFlippedStrictnessPredicateAndConstant(CmpPredicate Pred, Constant *C)
Convert an integer comparison with a constant RHS into an equivalent form with the strictness flipped...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
LLVM_ABI bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
LLVM_ABI void setFittedBranchWeights(Instruction &I, ArrayRef< uint64_t > Weights, bool IsExpected, bool ElideAllZero=false)
Variant of setBranchWeights where the Weights will be fit first to uint32_t by shifting right.
LLVM_ABI SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr)
Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind and providing the out param...
LLVM_ABI bool isTriviallyVectorizable(Intrinsic::ID ID)
Identify if the intrinsic is trivially vectorizable.
LLVM_ABI bool isCheckForZeroAndMulWithOverflow(Value *Op0, Value *Op1, bool IsAnd, Use *&Y)
Match one of the patterns up to the select/logic op: Op0 = icmp ne i4 X, 0 Agg = call { i4,...
LLVM_ABI std::optional< bool > isImpliedCondition(const Value *LHS, const Value *RHS, const DataLayout &DL, bool LHSIsTrue=true, unsigned Depth=0)
Return true if RHS is known to be implied true by LHS.
LLVM_ABI std::optional< DecomposedBitTest > decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate Pred, bool LookThroughTrunc=true, bool AllowNonZeroC=false, bool DecomposeAnd=false)
Decompose an icmp into the form ((X & Mask) pred C) if possible.
LLVM_ABI bool canIgnoreSignBitOfNaN(const Use &U)
Return true if the sign bit of the FP value can be ignored by the user when the value is NaN.
LLVM_ABI void findValuesAffectedByCondition(Value *Cond, bool IsAssume, function_ref< void(Value *)> InsertAffected)
Call InsertAffected on all Values whose known bits / value may be affected by the condition Cond.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static constexpr DenormalMode getIEEE()
SelectPatternFlavor Flavor
bool Ordered
Only applicable if Flavor is SPF_FMINNUM or SPF_FMAXNUM.
static bool isMinOrMax(SelectPatternFlavor SPF)
When implementing this min/max pattern as fcmp; select, does the fcmp have to be ordered?
SimplifyQuery getWithInstruction(const Instruction *I) const