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:
298 CondVTy->getElementCount() !=
310 if (TI->
getOpcode() != Instruction::BitCast &&
323 SI.getName() +
".v", &
SI);
328 Value *OtherOpT, *OtherOpF;
331 bool Swapped =
false) ->
Value * {
332 assert(!(Commute && Swapped) &&
333 "Commute and Swapped can't set at the same time");
338 MatchIsOpZero =
true;
343 MatchIsOpZero =
false;
348 if (!Commute && !Swapped)
357 MatchIsOpZero =
true;
362 MatchIsOpZero =
false;
376 FMF |=
SI.getFastMathFlags();
380 NewSelI->setFastMathFlags(FMF);
381 Instruction *NewFNeg = UnaryOperator::CreateFNeg(NewSel);
392 if (
TII && FII &&
TII->getIntrinsicID() == FII->getIntrinsicID()) {
394 if (
Value *MatchOp = getCommonOp(TI, FI,
true)) {
396 Builder.CreateSelect(
Cond, OtherOpT, OtherOpF,
"minmaxop", &
SI);
406 if (
TII->getIntrinsicID() == Intrinsic::ldexp) {
407 Value *LdexpVal0 =
TII->getArgOperand(0);
408 Value *LdexpExp0 =
TII->getArgOperand(1);
409 Value *LdexpVal1 = FII->getArgOperand(0);
410 Value *LdexpExp1 = FII->getArgOperand(1);
421 TII->getType(), Intrinsic::ldexp, {SelectVal, SelectExp});
428 auto CreateCmpSel = [&](std::optional<CmpPredicate>
P,
437 SI.getName() +
".v", &
SI);
491 if (BO->getOpcode() == Instruction::SDiv ||
492 BO->getOpcode() == Instruction::SRem || MatchIsOpZero)
498 SI.getName() +
".v", &
SI);
499 Value *Op0 = MatchIsOpZero ? MatchOp : NewSI;
500 Value *Op1 = MatchIsOpZero ? NewSI : MatchOp;
509 Type *ElementType = TGEP->getSourceElementType();
511 ElementType, Op0, Op1, TGEP->getNoWrapFlags() & FGEP->getNoWrapFlags());
527 LHSIntrinsic->getIntrinsicID() != RHSIntrinsic->getIntrinsicID() ||
528 !LHSIntrinsic->hasOneUse() || !RHSIntrinsic->hasOneUse())
534 case Intrinsic::cttz:
535 case Intrinsic::ctlz: {
539 Value *TV = LHSIntrinsic->getArgOperand(0);
540 Value *FV = RHSIntrinsic->getArgOperand(0);
544 Value *NewCall =
Builder.CreateBinaryIntrinsic(IID, NewSel, NewPoisonFlag);
548 case Intrinsic::ctpop: {
549 Value *TV = LHSIntrinsic->getArgOperand(0);
550 Value *FV = RHSIntrinsic->getArgOperand(0);
553 Value *NewCall =
Builder.CreateUnaryIntrinsic(IID, NewSel);
582 unsigned OpToFold = 0;
583 if ((SFO & 1) && FalseVal == TVI->getOperand(0))
585 else if ((SFO & 2) && FalseVal == TVI->getOperand(1))
593 FMF = FPO->getFastMathFlags();
595 TVI->getOpcode(), TVI->getType(),
true, FMF.
noSignedZeros());
596 Value *OOp = TVI->getOperand(2 - OpToFold);
602 (!OOpIsAPInt || !
isSelect01(
C->getUniqueInteger(), *OOpC)))
616 Value *NewSel =
Builder.CreateSelect(
SI.getCondition(), Swapped ?
C : OOp,
617 Swapped ? OOp :
C,
"", &
SI);
628 bool CanInferFiniteOperandsFromResult =
629 TVI->getOpcode() == Instruction::FAdd ||
630 TVI->getOpcode() == Instruction::FSub ||
631 TVI->getOpcode() == Instruction::FMul;
633 (CanInferFiniteOperandsFromResult &&
652 if (
Instruction *R = TryFoldSelectIntoOp(
SI, TrueVal, FalseVal,
false))
655 if (
Instruction *R = TryFoldSelectIntoOp(
SI, FalseVal, TrueVal,
true))
665 Value *CmpLHS = Cmp->getOperand(0);
666 Value *CmpRHS = Cmp->getOperand(1);
689 Builder.CreateBinaryIntrinsic(Intrinsic::smin, CmpRHS, CmpLHS);
690 return Builder.CreateNSWSub(CmpLHS,
SMin);
703 Value *CmpLHS = Cmp->getOperand(0);
704 Value *CmpRHS = Cmp->getOperand(1);
714 if (CmpRHS == TVal) {
727 return Builder.CreateBinaryIntrinsic(Intrinsic::smax, TVal, FVal);
733 return Builder.CreateBinaryIntrinsic(Intrinsic::smin, TVal, FVal);
739 return Builder.CreateBinaryIntrinsic(Intrinsic::umax, TVal, FVal);
749 return Builder.CreateBinaryIntrinsic(Intrinsic::umin, TVal, FVal);
766 if (!(Cmp->hasOneUse() && Cmp->getOperand(0)->hasOneUse() &&
798 Constant *One = ConstantInt::get(SelType, 1);
799 Value *MaskB = HasShift ? Builder.CreateShl(One, Z) : One;
800 Value *FullMask = Builder.CreateOr(
Y, MaskB);
801 Value *MaskedX = Builder.CreateAnd(
X, FullMask);
802 Value *ICmpNeZero = Builder.CreateIsNotNull(MaskedX);
803 return new ZExtInst(ICmpNeZero, SelType);
825 const APInt *C2, *C1;
839 FI->setHasNoSignedWrap(
false);
840 FI->setHasNoUnsignedWrap(
false);
878 return Builder.CreateAShr(
X,
Y, IC->
getName(), IsExact);
906 const APInt &AndMask,
bool CreateAnd,
909 if (!TrueVal->getType()->isIntOrIntVectorTy())
912 unsigned C1Log = AndMask.
logBase2();
933 if (IdentityC ==
nullptr || !IdentityC->isNullValue())
938 bool NeedShift = C1Log != C2Log;
939 bool NeedZExtTrunc =
Y->getType()->getScalarSizeInBits() !=
940 V->getType()->getScalarSizeInBits();
943 if ((NeedShift + NeedXor + NeedZExtTrunc + CreateAnd) >
949 V = Builder.CreateAnd(V, ConstantInt::get(V->getType(), AndMask));
953 V = Builder.CreateZExtOrTrunc(V,
Y->getType());
954 V = Builder.CreateShl(V, C2Log - C1Log);
955 }
else if (C1Log > C2Log) {
956 V = Builder.CreateLShr(V, C1Log - C2Log);
957 V = Builder.CreateZExtOrTrunc(V,
Y->getType());
959 V = Builder.CreateZExtOrTrunc(V,
Y->getType());
962 V = Builder.CreateXor(V, *C2);
964 auto *Res = Builder.CreateBinOp(BinOp->
getOpcode(),
Y, V);
966 BO->copyIRFlags(BinOp);
985 Constant *OrC = ConstantInt::get(Ty, *
C);
986 Value *NewSel = Builder.CreateSelect(
Cond, Zero, OrC,
"masksel", &Sel);
987 return BinaryOperator::CreateOr(
T, NewSel);
994 Constant *OrC = ConstantInt::get(Ty, *
C);
995 Value *NewSel = Builder.CreateSelect(
Cond, OrC, Zero,
"masksel", &Sel);
996 return BinaryOperator::CreateOr(
F, NewSel);
1017 auto *CondVal =
SI.getCondition();
1018 auto *TrueVal =
SI.getTrueValue();
1019 auto *FalseVal =
SI.getFalseValue();
1069 FalseValI->getOperand(0) ==
Y
1071 : (FalseValI->getOperand(1) ==
Y ? 1 : 2),
1081 const Value *FalseVal,
1101 return Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat,
A,
1102 ConstantInt::get(
A->getType(), 1));
1116 "Unexpected isUnsigned predicate!");
1122 bool IsNegative =
false;
1135 if (IsNegative && !TrueVal->hasOneUse() && !ICI->
hasOneUse())
1140 Value *Result = Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat,
A,
B);
1142 Result = Builder.CreateNeg(Result);
1148 const Value *FalseVal,
1165 return Builder.CreateBinaryIntrinsic(
1174 const Value *TrueVal,
1175 const Value *FalseVal,
1193 Value *Cmp0 = Cmp->getOperand(0);
1194 Value *Cmp1 = Cmp->getOperand(1);
1214 return Builder.CreateBinaryIntrinsic(
1215 Intrinsic::uadd_sat, Cmp0, ConstantInt::get(Cmp0->
getType(), 1));
1225 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp0,
1226 ConstantInt::get(Cmp0->
getType(), *
C));
1235 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp0,
1236 ConstantInt::get(Cmp0->
getType(), *
C));
1245 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp0,
1246 ConstantInt::get(Cmp0->
getType(), *
C));
1264 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat,
X,
Y);
1274 return Builder.CreateBinaryIntrinsic(
1284 return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp1,
Y);
1294 Value *Cmp0 = Cmp->getOperand(0);
1295 Value *Cmp1 = Cmp->getOperand(1);
1317 return Builder.CreateBinaryIntrinsic(
1318 Intrinsic::sadd_sat, Cmp0, ConstantInt::get(Cmp0->
getType(), 1));
1323 return Builder.CreateBinaryIntrinsic(
1324 Intrinsic::sadd_sat, Cmp0,
1342 Pred = Flipped->first;
1343 Cmp1 = Flipped->second;
1347 APInt Threshold = *SatC - *
C;
1351 return Builder.CreateBinaryIntrinsic(
1352 Intrinsic::sadd_sat, Cmp0, ConstantInt::get(Cmp0->
getType(), *
C));
1365 Pred = Flipped->first;
1366 Cmp1 = Flipped->second;
1371 APInt Threshold = *SatC - *
C;
1375 return Builder.CreateBinaryIntrinsic(
1376 Intrinsic::sadd_sat, Cmp0, ConstantInt::get(Cmp0->
getType(), *
C));
1394 return Builder.CreateBinaryIntrinsic(Intrinsic::sadd_sat,
X, Cmp1);
1403 return Builder.CreateBinaryIntrinsic(Intrinsic::sadd_sat,
X, Cmp0);
1411 if (!Cmp->hasOneUse())
1433 Value *
A = Cmp->getOperand(0);
1434 Value *
B = Cmp->getOperand(1);
1447 (TI->hasNoSignedWrap() || TI->hasNoUnsignedWrap()) &&
1448 (FI->hasNoSignedWrap() || FI->hasNoUnsignedWrap())) {
1455 TI->setHasNoUnsignedWrap(
false);
1456 if (!TI->hasNoSignedWrap())
1457 TI->setHasNoSignedWrap(TI->hasOneUse());
1458 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, TI, Builder.getTrue());
1465 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, TI,
1466 Builder.getFalse());
1473 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, FI,
1474 Builder.getFalse());
1481 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, FI,
1482 Builder.getFalse());
1489 return Builder.CreateBinaryIntrinsic(Intrinsic::abs, TI,
1490 Builder.getFalse());
1518 if (!
match(FalseVal,
1534 II->getModule(), Intrinsic::cttz,
II->getType());
1590 unsigned SizeOfInBits =
Count->getType()->getScalarSizeInBits();
1593 II->dropPoisonGeneratingAnnotations();
1605 II->dropUBImplyingAttrsAndMetadata();
1616 if (!
TrueVal->getType()->isIntOrIntVectorTy())
1656 if (!
I || !
I->hasOneUse() ||
1665 for (Use &U :
I->operands()) {
1698 bool Swapped =
false;
1699 if (
Cmp.isEquivalence(
true)) {
1702 }
else if (!
Cmp.isEquivalence()) {
1706 Value *CmpLHS =
Cmp.getOperand(0), *CmpRHS =
Cmp.getOperand(1);
1707 auto ReplaceOldOpWithNewOp = [&](
Value *OldOp,
1708 Value *NewOp) -> Instruction * {
1755 if (CanReplaceCmpLHSWithRHS) {
1756 if (Instruction *R = ReplaceOldOpWithNewOp(CmpLHS, CmpRHS))
1760 if (CanReplaceCmpRHSWithLHS) {
1761 if (Instruction *R = ReplaceOldOpWithNewOp(CmpRHS, CmpLHS))
1778 if ((CanReplaceCmpLHSWithRHS &&
1781 &DropFlags) == TrueVal) ||
1782 (CanReplaceCmpRHSWithLHS &&
1785 &DropFlags) == TrueVal)) {
1786 for (Instruction *
I : DropFlags) {
1787 I->dropPoisonGeneratingAnnotations();
1795 if (
FalseVal->getType()->isIntOrIntVectorTy(1) &&
1919 if (Cmp00->
getType() !=
X->getType() &&
X->hasOneUse())
1927 else if (!
match(Cmp00,
1935 Value *ReplacementLow, *ReplacementHigh;
1972 std::swap(ReplacementLow, ReplacementHigh);
1978 "Unexpected predicate type.");
1986 "Unexpected predicate type.");
1988 std::swap(ThresholdLowIncl, ThresholdHighExcl);
2004 if (
X->getType() != Sel0.
getType()) {
2014 assert(ReplacementLow && ReplacementHigh &&
2015 "Constant folding of ImmConstant cannot fail");
2021 Value *MaybeReplacedLow =
2027 ShouldReplaceHigh, ReplacementHigh, MaybeReplacedLow);
2071 Value *SelVal0, *SelVal1;
2080 auto MatchesSelectValue = [SelVal0, SelVal1](
Constant *
C) {
2081 return C->isElementWiseEqual(SelVal0) ||
C->isElementWiseEqual(SelVal1);
2085 if (MatchesSelectValue(C0))
2090 if (!FlippedStrictness)
2094 if (!MatchesSelectValue(FlippedStrictness->second))
2103 Cmp.getName() +
".inv");
2114 if (!
Cmp->hasOneUse())
2144 Value *TVal =
SI.getTrueValue();
2145 Value *FVal =
SI.getFalseValue();
2179 Op->dropPoisonGeneratingFlags();
2184 MMI && MMI->getLHS() == V &&
match(MMI->getRHS(),
m_APInt(OpC))) {
2186 {InvDomCR, ConstantRange(*OpC)});
2188 MMI->dropPoisonGeneratingAnnotations();
2251 foldSelectWithExtremeEqCond(CmpLHS, CmpRHS, TrueVal, FalseVal))
2283 Opcode = BOp->getOpcode();
2284 IsIntrinsic =
false;
2298 Opcode =
II->getIntrinsicID();
2306 const DataLayout &
DL =
Cmp->getDataLayout();
2315 if (C3 == FoldBinaryOpOrIntrinsic(C1, C2)) {
2318 }
else if (Flipped && C3 == FoldBinaryOpOrIntrinsic(Flipped->second, C2)) {
2320 RHS = Flipped->second;
2328 return Builder.CreateBinaryIntrinsic(Opcode, MinMax, C2);
2331 Value *BinOp =
Builder.CreateBinOp(BinOpc, MinMax, C2);
2336 if (BinOpc == Instruction::Add || BinOpc == Instruction::Sub ||
2337 BinOpc == Instruction::Mul) {
2340 willNotOverflow(BinOpc,
RHS, C2, *BinOpInst,
true))
2341 BinOpInst->setHasNoSignedWrap();
2343 willNotOverflow(BinOpc,
RHS, C2, *BinOpInst,
false))
2344 BinOpInst->setHasNoUnsignedWrap();
2362static Instruction *foldICmpUSubSatWithAndForMostSignificantBitCmp(
2368 const APInt *Constant1, *Constant2;
2386 auto *Ty =
A->getType();
2394 APInt AdjAP1 = *Constant1 - MostSignificantBit + 1;
2395 APInt AdjAP2 = *Constant2 - MostSignificantBit + 1;
2397 auto *Adj1 = ConstantInt::get(Ty, AdjAP1);
2398 auto *Adj2 = ConstantInt::get(Ty, AdjAP2);
2403 Constant *MSBConst = ConstantInt::get(Ty, MostSignificantBit);
2404 return BinaryOperator::CreateAnd(
Or, MSBConst);
2411 canonicalizeSPF(*ICI,
SI.getTrueValue(),
SI.getFalseValue(), *
this))
2414 if (
Value *V = foldSelectInstWithICmpConst(SI, ICI,
Builder))
2417 if (
Value *V = canonicalizeClampLike(SI, *ICI,
Builder, *
this))
2420 if (Instruction *NewSel =
2421 tryToReuseConstantFromSelectInComparison(SI, *ICI, *
this))
2423 if (Instruction *Folded =
2424 foldICmpUSubSatWithAndForMostSignificantBitCmp(SI, ICI,
Builder))
2435 if (Instruction *NewSel = foldSelectICmpEq(SI, ICI, *
this))
2445 InstCombiner::BuilderTy::InsertPointGuard Guard(
Builder);
2450 SI.swapProfMetadata();
2457 if (Instruction *V =
2464 if (Instruction *V = foldSelectCtlzToCttz(ICI, TrueVal, FalseVal,
Builder))
2467 if (Instruction *V = foldSelectZeroOrOnes(ICI, TrueVal, FalseVal,
Builder))
2473 if (
Value *V = foldSelectCttzCtlz(ICI, TrueVal, FalseVal, *
this))
2501 if (
C ==
A ||
C ==
B) {
2516 Value *CondVal =
SI.getCondition();
2521 if (!TI || !FI || !TI->hasOneUse() || !FI->hasOneUse())
2525 if ((TI->getOpcode() == Instruction::Sub &&
2526 FI->getOpcode() == Instruction::Add) ||
2527 (TI->getOpcode() == Instruction::FSub &&
2528 FI->getOpcode() == Instruction::FAdd)) {
2531 }
else if ((FI->getOpcode() == Instruction::Sub &&
2532 TI->getOpcode() == Instruction::Add) ||
2533 (FI->getOpcode() == Instruction::FSub &&
2534 TI->getOpcode() == Instruction::FAdd)) {
2540 Value *OtherAddOp =
nullptr;
2541 if (SubOp->getOperand(0) == AddOp->
getOperand(0)) {
2543 }
else if (SubOp->getOperand(0) == AddOp->
getOperand(1)) {
2551 if (
SI.getType()->isFPOrFPVectorTy()) {
2552 NegVal = Builder.
CreateFNeg(SubOp->getOperand(1));
2555 Flags &= SubOp->getFastMathFlags();
2556 NegInst->setFastMathFlags(Flags);
2559 NegVal = Builder.
CreateNeg(SubOp->getOperand(1));
2562 Value *NewTrueOp = OtherAddOp;
2563 Value *NewFalseOp = NegVal;
2567 SI.getName() +
".p", &
SI);
2569 if (
SI.getType()->isFPOrFPVectorTy()) {
2571 BinaryOperator::CreateFAdd(SubOp->getOperand(0), NewSel);
2574 Flags &= SubOp->getFastMathFlags();
2578 return BinaryOperator::CreateAdd(SubOp->getOperand(0), NewSel);
2591 Value *CondVal =
SI.getCondition();
2603 auto IsSignedSaturateLimit = [&](
Value *Limit,
bool IsAdd) {
2613 auto IsZeroOrOne = [](
const APInt &
C) {
return C.isZero() ||
C.isOne(); };
2630 IsMinMax(TrueVal, FalseVal))
2637 IsMinMax(FalseVal, TrueVal))
2643 IsMinMax(TrueVal, FalseVal))
2648 IsMinMax(FalseVal, TrueVal))
2653 IsMinMax(FalseVal, TrueVal))
2658 IsMinMax(TrueVal, FalseVal))
2666 if (
II->getIntrinsicID() == Intrinsic::uadd_with_overflow &&
2669 NewIntrinsicID = Intrinsic::uadd_sat;
2670 else if (
II->getIntrinsicID() == Intrinsic::usub_with_overflow &&
2673 NewIntrinsicID = Intrinsic::usub_sat;
2674 else if (
II->getIntrinsicID() == Intrinsic::sadd_with_overflow &&
2675 IsSignedSaturateLimit(TrueVal,
true))
2684 NewIntrinsicID = Intrinsic::sadd_sat;
2685 else if (
II->getIntrinsicID() == Intrinsic::ssub_with_overflow &&
2686 IsSignedSaturateLimit(TrueVal,
false))
2695 NewIntrinsicID = Intrinsic::ssub_sat;
2700 NewIntrinsicID,
SI.getType());
2716 if (ExtOpcode != Instruction::ZExt && ExtOpcode != Instruction::SExt)
2726 (!Cmp ||
Cmp->getOperand(0)->getType() != SmallType))
2750 Value *CondVal =
SI.getCondition();
2756 unsigned NumElts = CondValTy->getNumElements();
2758 Mask.reserve(NumElts);
2759 for (
unsigned i = 0; i != NumElts; ++i) {
2769 Mask.push_back(i + NumElts);
2822 if (TVal ==
A || TVal ==
B || FVal ==
A || FVal ==
B)
2839 if (TSrc ==
C && FSrc ==
D) {
2843 }
else if (TSrc ==
D && FSrc ==
C) {
2891 V = BI->getOperand(0);
2895 if (Extract->getIndices()[0] !=
I)
2901 auto isCompareSameAsValue = [](
Value *CmpVal,
Value *SelVal) {
2909 return IntC && FpC && IntC->getValue() == FpC->getValue().bitcastToAPInt();
2916 if (
Select->getCondition() ==
SI.getCondition())
2917 if (
Select->getFalseValue() ==
SI.getTrueValue() ||
2918 Select->getTrueValue() ==
SI.getFalseValue())
2922 auto *CmpXchg = isExtractFromCmpXchg(
SI.getCondition(), 1);
2929 if (
auto *
X = isExtractFromCmpXchg(
SI.getTrueValue(), 0))
2931 isCompareSameAsValue(
X->getCompareOperand(),
SI.getFalseValue()))
2932 return SI.getFalseValue();
2937 if (
auto *
X = isExtractFromCmpXchg(
SI.getFalseValue(), 0))
2939 isCompareSameAsValue(
X->getCompareOperand(),
SI.getTrueValue()))
2940 return SI.getFalseValue();
2964 Value *SV0, *SV1, *SA0, *SA1;
2973 if (Or0->
getOpcode() == BinaryOperator::LShr) {
2979 Or1->
getOpcode() == BinaryOperator::LShr &&
2980 "Illegal or(shift,shift) pair");
2995 bool IsFshl = (ShAmt == SA0);
2997 if ((IsFshl && TVal != SV0) || (!IsFshl && TVal != SV1))
3017 Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
3039 assert(TC != FC &&
"Expected equal select arms to simplify");
3043 bool IsTrueIfSignSet;
3061 Value *MagArg = ConstantFP::get(SelType,
abs(*TC));
3080 I->copyIRFlags(&Sel);
3083 M, Intrinsic::vector_reverse,
V->getType());
3091 return createSelReverse(
C,
X,
Y);
3095 return createSelReverse(
C,
X, FVal);
3100 return createSelReverse(
C, TVal,
Y);
3107 unsigned NumElts = VecTy->getNumElements();
3108 APInt PoisonElts(NumElts, 0);
3126 return new ShuffleVectorInst(
X, NewSel, Mask);
3131 return new ShuffleVectorInst(NewSel,
Y, Mask);
3140 return new ShuffleVectorInst(
X, NewSel, Mask);
3145 return new ShuffleVectorInst(NewSel,
Y, Mask);
3157 auto *IDomNode = DT[BB]->getIDom();
3163 Value *IfTrue, *IfFalse;
3179 if (TrueSucc == FalseSucc)
3195 else if (DT.
dominates(FalseEdge, Incoming))
3201 if (!DT.
dominates(Insn, Pred->getTerminator()))
3220 CandidateBlocks.
insert(
I->getParent());
3223 if (
auto *PN = foldSelectToPhiImpl(Sel, BB, DT, Builder))
3236 Value *CondVal =
SI.getCondition();
3241 Value *
Op, *RemRes, *Remainder;
3243 bool TrueIfSigned =
false;
3257 return BinaryOperator::CreateAnd(
Op,
Add);
3269 return FoldToBitwiseAnd(Remainder);
3278 return FoldToBitwiseAnd(ConstantInt::get(RemRes->
getType(), 2));
3288 Value *InnerCondVal =
SI.getCondition();
3289 Value *InnerTrueVal =
SI.getTrueValue();
3290 Value *InnerFalseVal =
SI.getFalseValue();
3292 "The type of inner condition must match with the outer.");
3294 return *Implied ? InnerTrueVal : InnerFalseVal;
3301 assert(
Op->getType()->isIntOrIntVectorTy(1) &&
3302 "Op must be either i1 or vector of i1.");
3303 if (
SI.getCondition()->getType() !=
Op->getType())
3305 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(SI,
Op, IsAnd,
DL))
3306 return createSelectInstWithUnknownProfile(
3316 Value *CondVal =
SI.getCondition();
3318 bool ChangedFMF =
false;
3319 for (
bool Swap : {
false,
true}) {
3357 if (FMF.
noNaNs() && !
SI.hasNoNaNs()) {
3358 SI.setHasNoNaNs(
true);
3361 if (FMF.
noInfs() && !
SI.hasNoInfs()) {
3362 SI.setHasNoInfs(
true);
3369 SI.setHasNoNaNs(
true);
3383 if (!
SI.hasNoSignedZeros() &&
3386 if (!
SI.hasNoNaNs() &&
3404 Instruction *NewFNeg = UnaryOperator::CreateFNeg(Fabs);
3413 for (
bool Swap : {
false,
true}) {
3429 if (Swap == TrueIfSigned && !CondVal->
hasOneUse() && !
TrueVal->hasOneUse())
3435 if (Swap != TrueIfSigned)
3440 return ChangedFMF ? &
SI :
nullptr;
3453foldSelectOfOrderedFAbsCmpOfNaNScrubbedValue(
SelectInst &
SI,
3468 Value *InnerSel =
SI.getTrueValue();
3473 if (!
match(InnerSel,
3480 auto MatchFAbsOfInnerSel = [&](
Value *
V) {
3485 if (!MatchFAbsOfInnerSel(Cmp0)) {
3486 if (!MatchFAbsOfInnerSel(Cmp1))
3536 Value *XBiasedHighBits =
SI.getFalseValue();
3549 const APInt *LowBitMaskCst;
3554 const APInt *BiasCst, *HighBitMaskCst;
3555 if (!
match(XBiasedHighBits,
3558 !
match(XBiasedHighBits,
3563 if (!LowBitMaskCst->
isMask())
3566 APInt InvertedLowBitMaskCst = ~*LowBitMaskCst;
3567 if (InvertedLowBitMaskCst != *HighBitMaskCst)
3570 APInt AlignmentCst = *LowBitMaskCst + 1;
3572 if (*BiasCst != AlignmentCst && *BiasCst != *LowBitMaskCst)
3577 if (*BiasCst == *LowBitMaskCst &&
impliesPoison(XBiasedHighBits,
X))
3578 return XBiasedHighBits;
3583 Type *Ty =
X->getType();
3584 Value *XOffset = Builder.
CreateAdd(
X, ConstantInt::get(Ty, *LowBitMaskCst),
3585 X->getName() +
".biased");
3586 Value *
R = Builder.
CreateAnd(XOffset, ConstantInt::get(Ty, *HighBitMaskCst));
3592struct DecomposedSelect {
3604foldSelectOfSymmetricSelect(
SelectInst &OuterSelVal,
3607 Value *OuterCond, *InnerCond, *InnerTrueVal, *InnerFalseVal;
3635 DecomposedSelect OuterSel;
3642 std::swap(OuterSel.TrueVal, OuterSel.FalseVal);
3650 Value *InnerSelVal = IsAndVariant ? OuterSel.FalseVal : OuterSel.TrueVal;
3658 DecomposedSelect InnerSel;
3659 if (!
match(InnerSelVal,
3666 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
3668 Value *AltCond =
nullptr;
3669 auto matchOuterCond = [OuterSel, IsAndVariant, &AltCond](
auto m_InnerCond) {
3674 return IsAndVariant ?
match(OuterSel.Cond,
3684 if (matchOuterCond(
m_Specific(InnerSel.Cond))) {
3689 std::swap(InnerSel.TrueVal, InnerSel.FalseVal);
3690 InnerSel.Cond = NotInnerCond;
3695 AltCond, IsAndVariant ? OuterSel.TrueVal : InnerSel.FalseVal,
3696 IsAndVariant ? InnerSel.TrueVal : OuterSel.FalseVal);
3699 IsAndVariant ? SelInner : InnerSel.TrueVal,
3700 !IsAndVariant ? SelInner : InnerSel.FalseVal);
3706static bool impliesPoisonOrCond(
const Value *ValAssumedPoison,
const Value *V,
3718 if (ICmp->hasSameSign() &&
3738 .getMaxValue() == 1;
3745 Value *CondVal =
SI.getCondition();
3748 Type *SelType =
SI.getType();
3765 if (impliesPoisonOrCond(FalseVal, CondVal,
false,
SQ)) {
3767 return BinaryOperator::CreateOr(CondVal, FalseVal);
3771 impliesPoisonOrCond(FalseVal,
B,
false,
SQ)) {
3786 auto AndFactorization = [&](
Value *Common,
Value *InnerCond,
3788 bool SelFirst =
false) -> Instruction * {
3789 Value *InnerSel =
Builder.CreateSelectWithUnknownProfile(
3793 if (FalseLogicAnd || (CondLogicAnd && Common ==
A))
3794 return createSelectInstWithUnknownProfile(Common, InnerSel, Zero);
3796 return BinaryOperator::CreateAnd(Common, InnerSel);
3800 return AndFactorization(
A,
B,
D);
3802 return AndFactorization(
A,
B,
C);
3804 return AndFactorization(
B,
A,
D);
3806 return AndFactorization(
B,
A,
C, CondLogicAnd && FalseLogicAnd);
3811 if (impliesPoisonOrCond(TrueVal, CondVal,
true,
SQ)) {
3813 return BinaryOperator::CreateAnd(CondVal, TrueVal);
3817 impliesPoisonOrCond(TrueVal,
B,
true,
SQ)) {
3832 auto OrFactorization = [&](
Value *Common,
Value *InnerCond,
3834 bool SelFirst =
false) -> Instruction * {
3835 Value *InnerSel =
Builder.CreateSelectWithUnknownProfile(
3839 if (TrueLogicOr || (CondLogicOr && Common ==
A))
3840 return createSelectInstWithUnknownProfile(Common, One, InnerSel);
3842 return BinaryOperator::CreateOr(Common, InnerSel);
3846 return OrFactorization(
A,
B,
D);
3848 return OrFactorization(
A,
B,
C);
3850 return OrFactorization(
B,
A,
D);
3852 return OrFactorization(
B,
A,
C, CondLogicOr && TrueLogicOr);
3913 return BinaryOperator::CreateXor(
A,
B);
3922 return createSelectInstWithUnknownProfile(TrueVal, OrV, Zero);
3927 Value *OrV =
Builder.CreateSelectWithUnknownProfile(NotC, One, TrueVal,
3929 return createSelectInstWithUnknownProfile(FalseVal, OrV, Zero);
3937 Value *AndV =
Builder.CreateSelectWithUnknownProfile(NotC, FalseVal, Zero,
3939 return createSelectInstWithUnknownProfile(TrueVal, One, AndV);
3947 return createSelectInstWithUnknownProfile(FalseVal, One, AndV);
3955 auto *FI =
new FreezeInst(*
Y, (*Y)->getName() +
".fr");
3961 if (
auto *V = foldBooleanAndOr(CondVal, Op1, SI, IsAnd,
3972 if (Res && *Res ==
false)
3978 if (Res && *Res ==
false)
3987 if (Res && *Res ==
true)
3993 if (Res && *Res ==
true)
4012 bool &ShouldDropNoWrap) {
4035 ShouldDropNoWrap =
false;
4041 auto MatchForward = [&](
Value *CommonAncestor) {
4042 const APInt *
C =
nullptr;
4043 if (CtlzOp == CommonAncestor)
4046 ShouldDropNoWrap =
true;
4051 ShouldDropNoWrap =
true;
4062 const APInt *
C =
nullptr;
4063 Value *CommonAncestor;
4064 if (MatchForward(Cond0)) {
4068 if (!MatchForward(CommonAncestor))
4106 Type *SelType =
SI.getType();
4115 Value *Cond0, *Ctlz, *CtlzOp;
4124 bool ShouldDropNoWrap;
4131 !isSafeToRemoveBitCeilSelect(Pred, Cond0, Cond1, CtlzOp,
BitWidth,
4135 if (ShouldDropNoWrap) {
4167 Value *TV =
SI.getTrueValue();
4168 Value *FV =
SI.getFalseValue();
4189 auto FlippedPredAndConst =
4191 if (!FlippedPredAndConst)
4193 Pred = FlippedPredAndConst->first;
4194 RHS = FlippedPredAndConst->second;
4212 CmpPredicate ExtendedCmpPredicate;
4232 CmpPredicate FalseBranchSelectPredicate;
4233 const APInt *InnerTV, *InnerFV;
4239 FalseBranchSelectPredicate =
4244 if (!InnerTV->
isOne()) {
4260 CmpPredicate InnerPred;
4262 const APInt *InnerTV, *InnerFV;
4271 bool CanSubOne = IsSigned ? !
C->isMinSignedValue() : !
C->isMinValue();
4273 APInt Cminus1 = *
C - 1;
4283 bool CanAddOne = IsSigned ? !
C->isMaxSignedValue() : !
C->isMaxValue();
4285 APInt Cplus1 = *
C + 1;
4294 Intrinsic::ID IID = IsSigned ? Intrinsic::scmp : Intrinsic::ucmp;
4297 SI,
Builder.CreateIntrinsic(
SI.getType(), IID, {LHS, RHS}));
4303 KnownFPClass Known =
4346 return Op->getType()->isIntOrIntVectorTy() &&
4347 hasAffectedValue(Op, Affected, Depth + 1);
4361 if (!SIFOp || !SIFOp->hasNoSignedZeros() || !SIFOp->hasNoNaNs())
4364 auto TryFoldIntoAddConstant =
4376 Swapped ?
X : Z,
"", &
SI);
4407 return TryFoldIntoAddConstant(Pred,
X, Z,
FAdd,
C,
false);
4411 return TryFoldIntoAddConstant(Pred,
X, Z,
FAdd,
C,
true);
4427 bool CreateAnd =
false;
4429 Value *CmpLHS, *CmpRHS;
4437 const APInt *AndRHS;
4444 AndMask = Res->Mask;
4457 V = Trunc->getOperand(0);
4458 AndMask =
APInt(
V->getType()->getScalarSizeInBits(), 1);
4460 CreateAnd = !Trunc->hasNoUnsignedWrap();
4469 CreateAnd, Builder))
4473 CreateAnd, Builder))
4486 auto *CondVal =
SI.getCondition();
4489 auto *SelTy =
SI.getType();
4491 if (!SelTy->isIntOrIntVectorTy() || SelTy->isIntOrIntVectorTy(1))
4506 if (matchNegNot(TrueVal, FalseVal,
X)) {
4509 return BinaryOperator::CreateSub(Mask,
X);
4513 if (matchNegNot(FalseVal, TrueVal,
X)) {
4515 return BinaryOperator::CreateSub(Mask,
X);
4522 Value *CondVal =
SI.getCondition();
4525 Type *SelType =
SI.getType();
4529 FMF = FPMO->getFastMathFlags();
4532 SQ.getWithInstruction(&SI)))
4535 if (Instruction *
I = canonicalizeSelectToShuffle(SI))
4538 if (Instruction *
I = canonicalizeScalarSelectOfVecs(SI, *
this))
4590 return new ZExtInst(CondVal, SelType);
4594 return new SExtInst(CondVal, SelType);
4599 return new ZExtInst(NotCond, SelType);
4605 return new SExtInst(NotCond, SelType);
4609 if (Instruction *
I = foldSelectNegNot(SI,
Builder))
4616 Value *Cmp0 = FCmp->getOperand(0), *Cmp1 = FCmp->getOperand(1);
4618 if ((Cmp0 == TrueVal && Cmp1 == FalseVal) ||
4619 (Cmp0 == FalseVal && Cmp1 == TrueVal)) {
4627 Value *NewCond =
Builder.CreateFCmpFMF(InvPred, Cmp0, Cmp1, FCmp,
4628 FCmp->getName() +
".inv");
4630 FastMathFlags FMF =
SI.getFastMathFlags();
4631 if (FCmp->hasNoNaNs())
4633 if (FCmp->hasNoInfs())
4636 Builder.CreateSelectFMF(NewCond, FalseVal, TrueVal, FMF);
4655 Value *MatchCmp0 =
nullptr;
4656 Value *MatchCmp1 =
nullptr;
4668 if (Cmp0 == MatchCmp0 &&
4669 matchFMulByZeroIfResultEqZero(*
this, Cmp0, Cmp1, MatchCmp1, MatchCmp0,
4670 SI, SIFPOp->hasNoSignedZeros()))
4710 bool CanonicalizeIfNotNan =
4713 if (RcpIfNan || CanonicalizeIfNotNan) {
4715 DenormalMode
Mode =
F.getDenormalMode(FPSem);
4721 if (CanonicalizeIfNotNan)
4735 new FreezeInst(Cmp0, Cmp0->
getName() +
".fr"),
4736 FCmp->getIterator());
4744 if (CanonicalizeIfNotNan) {
4765 if (RcpIfNan && (
Mode.inputsAreZero() ||
Mode.outputsAreZero()))
4794 if (FCmp && FCmp->hasNoNaNs() &&
4795 (SIFPOp->hasNoSignedZeros() ||
4796 (SIFPOp->hasOneUse() &&
4801 Builder.CreateBinaryIntrinsic(Intrinsic::maxnum,
X,
Y, &SI);
4805 BinIntrInst->setHasNoInfs(FCmp->hasNoInfs());
4811 BinIntrInst->setHasNoSignedZeros(
true);
4814 BinIntrInst->setHasNoNaNs(
true);
4821 Builder.CreateBinaryIntrinsic(Intrinsic::minnum,
X,
Y, &SI);
4823 BinIntrInst->setHasNoInfs(FCmp->hasNoInfs());
4824 BinIntrInst->setHasNoSignedZeros(
true);
4825 BinIntrInst->setHasNoNaNs(
true);
4833 if (Instruction *Fabs = foldSelectWithFCmpToFabs(SI, *
this))
4836 if (Instruction *
I = foldSelectOfOrderedFAbsCmpOfNaNScrubbedValue(SI, *
this))
4848 if (
Value *V = foldSelectBitTest(SI, CondVal, TrueVal, FalseVal,
Builder,
SQ))
4851 if (Instruction *
Add = foldAddSubSelect(SI,
Builder))
4853 if (Instruction *
Add = foldOverflowingAddSubSelect(SI,
Builder))
4863 if (TI && FI && TI->getOpcode() == FI->getOpcode())
4873 if (Instruction *
I = foldSelectWithSRem(SI, *
this,
Builder))
4878 auto SelectGepWithBase = [&](GetElementPtrInst *Gep,
Value *
Base,
4879 bool Swap) -> GetElementPtrInst * {
4893 Builder.CreateSelect(CondVal, NewT, NewF,
SI.getName() +
".idx", &SI);
4898 if (
auto *NewGep = SelectGepWithBase(TrueGep, FalseVal,
false))
4901 if (
auto *NewGep = SelectGepWithBase(FalseGep, TrueVal,
true))
4917 RHS2, SI, SPF,
RHS))
4921 RHS2, SI, SPF,
LHS))
4930 bool IsCastNeeded =
LHS->
getType() != SelType;
4935 ((CmpLHS !=
LHS && CmpLHS !=
RHS) ||
4936 (CmpRHS !=
LHS && CmpRHS !=
RHS)))) {
4950 Value *NewCast =
Builder.CreateCast(CastOp, NewSI, SelType);
4962 if (TrueSI->getCondition()->getType() == CondVal->
getType()) {
4965 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(
4966 *TrueSI, CondVal,
true,
DL))
4972 if (TrueSI->hasOneUse()) {
4973 Value *
And =
nullptr, *OtherVal =
nullptr;
4975 if (TrueSI->getFalseValue() == FalseVal) {
4976 And =
Builder.CreateLogicalAnd(CondVal, TrueSI->getCondition(),
"",
4979 OtherVal = TrueSI->getTrueValue();
4982 else if (TrueSI->getTrueValue() == FalseVal) {
4983 Value *InvertedCond =
Builder.CreateNot(TrueSI->getCondition());
4984 And =
Builder.CreateLogicalAnd(CondVal, InvertedCond,
"",
4987 OtherVal = TrueSI->getFalseValue();
4989 if (
And && OtherVal) {
5000 if (FalseSI->getCondition()->getType() == CondVal->
getType()) {
5003 if (
Value *V = simplifyNestedSelectsUsingImpliedCond(
5004 *FalseSI, CondVal,
false,
DL))
5007 if (FalseSI->hasOneUse()) {
5008 Value *
Or =
nullptr, *OtherVal =
nullptr;
5010 if (FalseSI->getTrueValue() == TrueVal) {
5011 Or =
Builder.CreateLogicalOr(CondVal, FalseSI->getCondition(),
"",
5014 OtherVal = FalseSI->getFalseValue();
5017 else if (FalseSI->getFalseValue() == TrueVal) {
5018 Value *InvertedCond =
Builder.CreateNot(FalseSI->getCondition());
5019 Or =
Builder.CreateLogicalOr(CondVal, InvertedCond,
"",
5022 OtherVal = FalseSI->getTrueValue();
5024 if (
Or && OtherVal) {
5041 BinaryOperator *TrueBO;
5044 if (TrueBOSI->getCondition() == CondVal) {
5051 if (TrueBOSI->getCondition() == CondVal) {
5060 BinaryOperator *FalseBO;
5063 if (FalseBOSI->getCondition() == CondVal) {
5070 if (FalseBOSI->getCondition() == CondVal) {
5083 SI.swapProfMetadata();
5104 if (Instruction *BitCastSel = foldSelectCmpBitcasts(SI,
Builder))
5108 if (
Value *V = foldSelectCmpXchg(SI))
5114 if (Instruction *Funnel = foldSelectFunnelShift(SI,
Builder))
5117 if (Instruction *Copysign = foldSelectToCopysign(SI,
Builder))
5120 if (Instruction *PN = foldSelectToPhi(SI,
DT,
Builder))
5123 if (
Value *V = foldRoundUpIntegerWithPow2Alignment(SI,
Builder))
5138 MaskedInst->setArgOperand(2, FalseVal );
5153 bool CanMergeSelectIntoLoad =
false;
5157 if (CanMergeSelectIntoLoad) {
5160 MaskedInst->setArgOperand(2, TrueVal );
5165 if (Instruction *
I = foldSelectOfSymmetricSelect(SI,
Builder))
5168 if (Instruction *
I = foldNestedSelects(SI,
Builder))
5178 if (Instruction *
I = foldBitCeil(SI,
Builder, *
this))
5192 auto FoldSelectWithAndOrCond = [&](
bool IsAnd,
Value *
A,
5193 Value *
B) -> Instruction * {
5195 SQ.getWithInstruction(&SI))) {
5203 if (NewTrueVal == TrueVal && NewFalseVal == FalseVal &&
5214 if (
Value *V = canonicalizeSPF(*Cmp, TrueVal, FalseVal, *
this)) {
5216 A, IsAnd ? V : TrueVal, IsAnd ? FalseVal : V,
"",
nullptr,
5226 if (Instruction *
I = FoldSelectWithAndOrCond(
true,
LHS,
RHS))
5228 if (Instruction *
I = FoldSelectWithAndOrCond(
true,
RHS,
LHS))
5231 if (Instruction *
I = FoldSelectWithAndOrCond(
false,
LHS,
RHS))
5233 if (Instruction *
I = FoldSelectWithAndOrCond(
false,
RHS,
LHS))
5239 if (Instruction *
I = FoldSelectWithAndOrCond(
true,
LHS,
RHS))
5242 if (Instruction *
I = FoldSelectWithAndOrCond(
false,
LHS,
RHS))
5249 return BinaryOperator::CreateXor(CondVal, FalseVal);
5256 CondContext CC(CondVal);
5258 CC.AffectedValues.insert(V);
5260 SimplifyQuery Q =
SQ.getWithInstruction(&SI).getWithCondContext(CC);
5261 if (!CC.AffectedValues.empty()) {
5263 hasAffectedValue(TrueVal, CC.AffectedValues, 0)) {
5272 hasAffectedValue(FalseVal, CC.AffectedValues, 0)) {
5287 if (TrueVal == Trunc)
5289 if (FalseVal == Trunc)
5293 if (TrueVal == Trunc)
5296 if (FalseVal == Trunc)
5300 Value *MaskedLoadPtr;
5305 TrueVal->getType(), MaskedLoadPtr,
5307 CondVal, FalseVal));
5312 unsigned BitWidth =
SI.getType()->getScalarSizeInBits();
5314 Value *CmpLHS, *CmpRHS;
5331 SI.getModule(), Intrinsic::scmp, {SI.getType(), SI.getType()});
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< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
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 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 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 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 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.
Machine Check Debug Module
uint64_t IntrinsicInst * II
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > & 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 countLeadingZeros() const
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.
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.
This class represents a function call, abstracting a target machine's calling convention.
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="")
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
Value * 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
IRBuilder< TargetFolder, IRBuilderCallbackInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
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.
void computeKnownBits(const Value *V, KnownBits &Known, const Instruction *CxtI, unsigned Depth=0) const
void addToWorklist(Instruction *I)
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
const SimplifyQuery & getSimplifyQuery() const
static Constant * AddOne(Constant *C)
Add one to a Constant.
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, const Instruction *CxtI=nullptr, unsigned Depth=0)
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 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.
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...
bool contains(ConstPtrType Ptr) const
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)
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.
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.
@ C
The default llvm calling convention, compatible with C.
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.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
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.
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)
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)
m_Intrinsic_Ty< Opnd0 >::Ty m_FCanonicalize(const Opnd0 &Op0)
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 ?
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.
constantexpr_match m_ConstantExpr()
Match a constant expression or a constant that contains a constant expression.
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'.
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_MaskedLoad(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
Matches MaskedLoad Intrinsic.
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.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
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.
match_combine_or< MaxMin_match< FCmpInst, LHS, RHS, ofmin_pred_ty >, MaxMin_match< FCmpInst, LHS, RHS, ufmin_pred_ty > > m_OrdOrUnordFMin(const LHS &L, const RHS &R)
Match an 'ordered' or 'unordered' floating point minimum function.
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.
MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > m_SMin(const LHS &L, const RHS &R)
cst_pred_ty< is_any_apint > m_AnyIntegralConstant()
Match an integer or vector with any integral constant.
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_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.
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.
MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty > m_UMax(const LHS &L, const RHS &R)
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.
auto m_MaxOrMin(const LHS &L, const RHS &R)
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)
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_MaskedGather(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
Matches MaskedGather Intrinsic.
match_combine_or< MaxMin_match< FCmpInst, LHS, RHS, ofmax_pred_ty >, MaxMin_match< FCmpInst, LHS, RHS, ufmax_pred_ty > > m_OrdOrUnordFMax(const LHS &L, const RHS &R)
Match an 'ordered' or 'unordered' floating point maximum function.
CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_FShl(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty > m_SMax(const LHS &L, const RHS &R)
cst_pred_ty< is_maxsignedvalue > m_MaxSignedValue()
Match an integer or vector with values having all bits except for the high bit set (0x7f....
m_Intrinsic_Ty< Opnd0 >::Ty m_Ctpop(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.
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)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
cstfp_pred_ty< is_pos_zero_fp > m_PosZeroFP()
Match a floating-point positive zero.
LogicalOp_match< LHS, RHS, Instruction::And, true > m_c_LogicalAnd(const LHS &L, const RHS &R)
Matches L && R with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FDiv > m_FDiv(const LHS &L, const RHS &R)
m_Intrinsic_Ty< Opnd0 >::Ty m_VecReverse(const Opnd0 &Op0)
BinOpPred_match< LHS, RHS, is_irem_op > m_IRem(const LHS &L, const RHS &R)
Matches integer remainder operations.
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_Cttz(const Opnd0 &Op0, const Opnd1 &Op1)
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_FShr(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
brc_match< Cond_t, match_bind< BasicBlock >, match_bind< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_Ctlz(const Opnd0 &Op0, const Opnd1 &Op1)
BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)
auto m_Undef()
Match an arbitrary undef constant.
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.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
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)
m_Intrinsic_Ty< Opnd0 >::Ty m_FAbs(const Opnd0 &Op0)
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.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > m_UMin(const LHS &L, const RHS &R)
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.
FunctionAddr VTableAddr Value
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.
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.
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 Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Instruction *I=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
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.
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 void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=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 SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)
Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind and providing the out param...
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.
FunctionAddr VTableAddr Count
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 * ConstantFoldBinaryIntrinsic(Intrinsic::ID ID, Constant *LHS, Constant *RHS, Type *Ty)
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.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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, unsigned Depth=0)
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()).
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 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 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()
bool isConstant() const
Returns true if we know the value of all bits.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
bool isKnownNeverInfinity() const
Return true if it's known this can never be an infinity.
bool isKnownNeverNaN() const
Return true if it's known this can never be a nan.
bool signBitIsZeroOrNaN() const
Return true if the sign bit must be 0, ignoring the sign of nans.
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