19using namespace PatternMatch;
21#define DEBUG_TYPE "instcombine"
39 unsigned MaximalPossibleTotalShiftAmount =
42 APInt MaximalRepresentableShiftAmount =
44 return MaximalRepresentableShiftAmount.
uge(MaximalPossibleTotalShiftAmount);
60 bool AnalyzeForSignBitExtraction) {
72 Value *Trunc =
nullptr;
91 if (AnalyzeForSignBitExtraction && !HadTwoRightShifts)
98 if (!IdenticalShOpcodes && !AnalyzeForSignBitExtraction)
104 if (Trunc && !AnalyzeForSignBitExtraction &&
109 auto *NewShAmt = dyn_cast_or_null<Constant>(
114 unsigned NewShAmtBitWidth = NewShAmt->getType()->getScalarSizeInBits();
115 unsigned XBitWidth =
X->getType()->getScalarSizeInBits();
118 APInt(NewShAmtBitWidth, XBitWidth))))
126 if (HadTwoRightShifts && (Trunc || AnalyzeForSignBitExtraction)) {
130 APInt(NewShAmtBitWidth, XBitWidth - 1))))
133 if (AnalyzeForSignBitExtraction)
137 assert(IdenticalShOpcodes &&
"Should not get here with different shifts.");
139 if (NewShAmt->getType() !=
X->getType()) {
141 X->getType(),
SQ.
DL);
153 if (ShiftOpcode == Instruction::BinaryOps::Shl) {
193 "The input must be 'shl'!");
208 bool HadTrunc = WidestTy != NarrowestTy;
240 MaskShAmt, ShiftShAmt,
false,
false, Q));
251 SumOfShAmts, ConstantInt::get(SumOfShAmts->getType()->getScalarType(),
254 Instruction::ZExt, SumOfShAmts, ExtendedTy, Q.
DL);
255 if (!ExtendedSumOfShAmts)
261 Instruction::Shl, ExtendedAllOnes, ExtendedSumOfShAmts, Q.
DL);
262 if (!ExtendedInvertedMask)
279 ShiftShAmt, MaskShAmt,
false,
false, Q));
291 ShAmtsDiff, ConstantInt::get(ShAmtsDiff->getType()->getScalarType(),
300 if (!ExtendedNumHighBitsToClear)
306 ExtendedNumHighBitsToClear, Q.
DL);
350 assert(
I.isShift() &&
"Expected a shift as input");
351 auto *BinInst = dyn_cast<BinaryOperator>(
I.getOperand(0));
353 (!BinInst->isBitwiseLogicOp() &&
354 BinInst->getOpcode() != Instruction::Add &&
355 BinInst->getOpcode() != Instruction::Sub) ||
356 !BinInst->hasOneUse())
365 if ((BinInst->getOpcode() == Instruction::Add ||
366 BinInst->getOpcode() == Instruction::Sub) &&
367 ShiftOpcode != Instruction::Shl)
370 Type *Ty =
I.getType();
375 auto matchFirstShift = [&](
Value *V,
Value *W) {
387 bool FirstShiftIsOp1 =
false;
388 if (matchFirstShift(BinInst->getOperand(0), BinInst->getOperand(1)))
389 Y = BinInst->getOperand(1);
390 else if (matchFirstShift(BinInst->getOperand(1), BinInst->getOperand(0))) {
391 Y = BinInst->getOperand(0);
392 FirstShiftIsOp1 = BinInst->getOpcode() == Instruction::Sub;
400 Value *Op1 = FirstShiftIsOp1 ? NewShift2 : NewShift1;
401 Value *Op2 = FirstShiftIsOp1 ? NewShift1 : NewShift2;
409 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
411 Type *Ty =
I.getType();
425 if (isa<Constant>(Op0))
426 if (
SelectInst *SI = dyn_cast<SelectInst>(Op1))
435 if (
auto *NewShift = cast_or_null<Instruction>(
447 if (
I.getOpcode() == Instruction::Shl) {
466 assert(!
AC->isZero() &&
"Expected simplify of shifted zero");
467 unsigned PosOffset = (-*AddC).getZExtValue();
469 auto isSuitableForPreShift = [PosOffset, &
I,
AC]() {
470 switch (
I.getOpcode()) {
473 case Instruction::Shl:
474 return (
I.hasNoSignedWrap() ||
I.hasNoUnsignedWrap()) &&
475 AC->eq(
AC->lshr(PosOffset).shl(PosOffset));
476 case Instruction::LShr:
477 return I.isExact() &&
AC->eq(
AC->shl(PosOffset).lshr(PosOffset));
478 case Instruction::AShr:
479 return I.isExact() &&
AC->eq(
AC->shl(PosOffset).ashr(PosOffset));
482 if (isSuitableForPreShift()) {
483 Constant *NewC = ConstantInt::get(Ty,
I.getOpcode() == Instruction::Shl
484 ?
AC->lshr(PosOffset)
485 :
AC->shl(PosOffset));
488 if (
I.getOpcode() == Instruction::Shl) {
516 if ((
I.getOpcode() == Instruction::LShr ||
517 I.getOpcode() == Instruction::AShr) &&
519 isa<CmpIntrinsic>(CmpIntr) &&
541 const APInt *InnerShiftConst;
548 bool IsInnerShl = InnerShift->
getOpcode() == Instruction::Shl;
549 if (IsInnerShl == IsOuterShl)
555 if (*InnerShiftConst == OuterShAmt)
565 if (InnerShiftConst->
ugt(OuterShAmt) && InnerShiftConst->
ult(TypeWidth)) {
568 IsInnerShl ? TypeWidth - InnerShAmt : InnerShAmt - OuterShAmt;
594 if (!
I)
return false;
598 if (!
I->hasOneUse())
return false;
600 switch (
I->getOpcode()) {
601 default:
return false;
602 case Instruction::And:
603 case Instruction::Or:
604 case Instruction::Xor:
609 case Instruction::Shl:
610 case Instruction::LShr:
613 case Instruction::Select: {
615 Value *TrueVal = SI->getTrueValue();
616 Value *FalseVal = SI->getFalseValue();
620 case Instruction::PHI: {
630 case Instruction::Mul: {
631 const APInt *MulConst;
633 return !IsLeftShift &&
match(
I->getOperand(1),
m_APInt(MulConst)) &&
644 bool IsInnerShl = InnerShift->
getOpcode() == Instruction::Shl;
654 auto NewInnerShift = [&](
unsigned ShAmt) {
655 InnerShift->
setOperand(1, ConstantInt::get(ShType, ShAmt));
668 if (IsInnerShl == IsOuterShl) {
670 if (InnerShAmt + OuterShAmt >= TypeWidth)
673 return NewInnerShift(InnerShAmt + OuterShAmt);
679 if (InnerShAmt == OuterShAmt) {
680 APInt Mask = IsInnerShl
684 ConstantInt::get(ShType, Mask));
685 if (
auto *AndI = dyn_cast<Instruction>(
And)) {
692 assert(InnerShAmt > OuterShAmt &&
693 "Unexpected opposite direction logical shift pair");
699 return NewInnerShift(InnerShAmt - OuterShAmt);
707 if (
Constant *
C = dyn_cast<Constant>(V)) {
717 switch (
I->getOpcode()) {
719 case Instruction::And:
720 case Instruction::Or:
721 case Instruction::Xor:
729 case Instruction::Shl:
730 case Instruction::LShr:
734 case Instruction::Select:
740 case Instruction::PHI: {
747 isLeftShift, IC,
DL));
750 case Instruction::Mul: {
751 assert(!isLeftShift &&
"Unexpected shift direction!");
754 unsigned TypeWidth =
I->getType()->getScalarSizeInBits();
756 auto *
And = BinaryOperator::CreateAnd(Neg,
757 ConstantInt::get(
I->getType(), Mask));
771 case Instruction::Add:
772 return Shift.
getOpcode() == Instruction::Shl;
773 case Instruction::Or:
774 case Instruction::And:
776 case Instruction::Xor:
789 bool IsLeftShift =
I.getOpcode() == Instruction::Shl;
795 R->setHasNoUnsignedWrap(
I.hasNoUnsignedWrap() &&
799 R->setIsExact(
I.isExact() && BO0->
isExact());
803 Type *Ty =
I.getType();
812 Constant *NegDivC = ConstantInt::get(Ty, -(*DivC));
816 auto ExtOpcode = (
I.getOpcode() == Instruction::AShr) ? Instruction::SExt
826 "Shift over the type width should have been removed already");
830 if (
I.getOpcode() != Instruction::AShr &&
833 dbgs() <<
"ICE: GetShiftedValue propagating shift through expression"
834 " to eliminate shift:\n IN: "
835 << *Op0 <<
"\n SH: " <<
I <<
"\n");
847 if (
auto *Op0BO = dyn_cast<BinaryOperator>(Op0)) {
879 if (!isa<Constant>(FalseVal) && TBO->
getOperand(0) == FalseVal &&
896 if (!isa<Constant>(TrueVal) && FBO->
getOperand(0) == TrueVal &&
923 assert(
I.getOpcode() == Instruction::LShr);
926 Value *ShiftAmt =
I.getOperand(1);
927 Type *Ty =
I.getType();
932 const APInt *ShAmtAPInt =
nullptr;
933 Value *
X =
nullptr, *
Y =
nullptr;
944 if (
X->getType()->getScalarSizeInBits() != ShAmt ||
945 Y->getType()->getScalarSizeInBits() != ShAmt)
949 if (!
Add->hasOneUse()) {
954 TruncInst *Trunc = dyn_cast<TruncInst>(U);
972 if (!
Add->hasOneUse()) {
983 assert(
I.isShift() &&
"Expected a shift as input");
985 if (
I.getOpcode() == Instruction::Shl) {
986 if (
I.hasNoUnsignedWrap() &&
I.hasNoSignedWrap())
998 if (
match(
I.getOperand(1), m_Intrinsic<Intrinsic::cttz>(
1013 bool Changed =
false;
1015 if (
I.getOpcode() == Instruction::Shl) {
1018 I.setHasNoUnsignedWrap();
1022 if (!
I.hasNoSignedWrap()) {
1026 I.setHasNoSignedWrap();
1036 I.setIsExact(Changed);
1045 I.hasNoSignedWrap(),
I.hasNoUnsignedWrap(), Q))
1057 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1058 Type *Ty =
I.getType();
1063 unsigned ShAmtC =
C->getZExtValue();
1069 unsigned SrcWidth =
X->getType()->getScalarSizeInBits();
1070 if (ShAmtC < SrcWidth &&
1078 return BinaryOperator::CreateAnd(
X, ConstantInt::get(Ty, Mask));
1085 if (ShrAmt < ShAmtC) {
1087 Constant *ShiftDiff = ConstantInt::get(Ty, ShAmtC - ShrAmt);
1088 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
1089 NewShl->setHasNoUnsignedWrap(
1090 I.hasNoUnsignedWrap() ||
1092 cast<Instruction>(Op0)->getOpcode() == Instruction::LShr &&
1093 I.hasNoSignedWrap()));
1094 NewShl->setHasNoSignedWrap(
I.hasNoSignedWrap());
1097 if (ShrAmt > ShAmtC) {
1099 Constant *ShiftDiff = ConstantInt::get(Ty, ShrAmt - ShAmtC);
1101 cast<BinaryOperator>(Op0)->
getOpcode(),
X, ShiftDiff);
1102 NewShr->setIsExact(
true);
1110 if (ShrAmt < ShAmtC) {
1112 Constant *ShiftDiff = ConstantInt::get(Ty, ShAmtC - ShrAmt);
1113 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
1114 NewShl->setHasNoUnsignedWrap(
1115 I.hasNoUnsignedWrap() ||
1117 cast<Instruction>(Op0)->getOpcode() == Instruction::LShr &&
1118 I.hasNoSignedWrap()));
1119 NewShl->setHasNoSignedWrap(
I.hasNoSignedWrap());
1122 return BinaryOperator::CreateAnd(NewShl, ConstantInt::get(Ty, Mask));
1124 if (ShrAmt > ShAmtC) {
1126 Constant *ShiftDiff = ConstantInt::get(Ty, ShrAmt - ShAmtC);
1127 auto *OldShr = cast<BinaryOperator>(Op0);
1130 NewShr->setIsExact(OldShr->isExact());
1133 return BinaryOperator::CreateAnd(NewShr, ConstantInt::get(Ty, Mask));
1143 unsigned ShDiff = ShrAmtC > ShAmtC ? ShrAmtC - ShAmtC : ShAmtC - ShrAmtC;
1144 Constant *ShiftDiffC = ConstantInt::get(
X->getType(), ShDiff);
1145 auto ShiftOpc = ShrAmtC > ShAmtC ? Shr->
getOpcode() : Instruction::Shl;
1154 return BinaryOperator::CreateAnd(Trunc, ConstantInt::get(Ty, Mask));
1160 switch (BinOpcode) {
1163 case Instruction::Add:
1164 case Instruction::And:
1165 case Instruction::Or:
1166 case Instruction::Xor:
1167 case Instruction::Sub:
1175 isSuitableBinOpcode(Op0BO->
getOpcode())) {
1196 unsigned Op1Val =
C->getLimitedValue(
BitWidth);
1198 Constant *Mask = ConstantInt::get(Ty, Bits);
1199 return BinaryOperator::CreateAnd(
B, Mask);
1210 X->getName() +
".mask");
1212 if (
auto *Disjoint = dyn_cast<PossiblyDisjointInst>(Op0BO);
1213 Disjoint && Disjoint->isDisjoint())
1214 cast<PossiblyDisjointInst>(NewOp)->setIsDisjoint(
true);
1223 return BinaryOperator::CreateSub(NewLHS, NewShift);
1236 return BinaryOperator::CreateAnd(Mask,
X);
1242 return BinaryOperator::CreateShl(
AllOnes, Op1);
1263 return BinaryOperator::CreateLShr(
1271 return BinaryOperator::CreateAnd(NegX,
X);
1289 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1290 Type *Ty =
I.getType();
1306 auto *NewSub = BinaryOperator::CreateNUWSub(
X, NewLshr);
1307 NewSub->setHasNoSignedWrap(
1316 return BinaryOperator::CreateAnd(
X,
Y);
1323 auto *NewSub = BinaryOperator::CreateNUWSub(NewLshr,
Y);
1324 NewSub->setHasNoSignedWrap(
1330 switch (BinOpcode) {
1333 case Instruction::Add:
1334 case Instruction::And:
1335 case Instruction::Or:
1336 case Instruction::Xor:
1347 if (isSuitableBinOpcode(Op0OB->
getOpcode())) {
1348 if (
auto *OBO = dyn_cast<OverflowingBinaryOperator>(Op0);
1349 !OBO || OBO->hasNoUnsignedWrap()) {
1351 Y, Op1,
"",
I.isExact() && Op0OB->
getOpcode() != Instruction::And);
1354 NewBinOp->setHasNoUnsignedWrap(
true);
1355 NewBinOp->setHasNoSignedWrap(OBO->hasNoSignedWrap());
1356 }
else if (
auto *Disjoint = dyn_cast<PossiblyDisjointInst>(Op0)) {
1357 cast<PossiblyDisjointInst>(NewBinOp)->setIsDisjoint(
1358 Disjoint->isDisjoint());
1366 unsigned ShAmtC =
C->getZExtValue();
1367 auto *
II = dyn_cast<IntrinsicInst>(Op0);
1369 (
II->getIntrinsicID() == Intrinsic::ctlz ||
1370 II->getIntrinsicID() == Intrinsic::cttz ||
1371 II->getIntrinsicID() == Intrinsic::ctpop)) {
1375 bool IsPop =
II->getIntrinsicID() == Intrinsic::ctpop;
1383 if (C1->
ult(ShAmtC)) {
1385 Constant *ShiftDiff = ConstantInt::get(Ty, ShAmtC - ShlAmtC);
1388 auto *NewLShr = BinaryOperator::CreateLShr(
X, ShiftDiff);
1389 NewLShr->setIsExact(
I.isExact());
1396 return BinaryOperator::CreateAnd(NewLShr, ConstantInt::get(Ty, Mask));
1398 }
else if (C1->
ugt(ShAmtC)) {
1400 Constant *ShiftDiff = ConstantInt::get(Ty, ShlAmtC - ShAmtC);
1403 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
1404 NewShl->setHasNoUnsignedWrap(
true);
1405 NewShl->setHasNoSignedWrap(ShAmtC > 0);
1412 return BinaryOperator::CreateAnd(NewShl, ConstantInt::get(Ty, Mask));
1418 return BinaryOperator::CreateAnd(
X, ConstantInt::get(Ty, Mask));
1430 unsigned Op1Val =
C->getLimitedValue(
BitWidth);
1432 Constant *Mask = ConstantInt::get(Ty, Bits);
1433 return BinaryOperator::CreateAnd(NewAdd, Mask);
1437 (!Ty->
isIntegerTy() || shouldChangeType(Ty,
X->getType()))) {
1439 "Big shift not simplified to zero?");
1446 unsigned SrcTyBitWidth =
X->getType()->getScalarSizeInBits();
1448 if (SrcTyBitWidth == 1) {
1449 auto *NewC = ConstantInt::get(
1454 if ((!Ty->
isIntegerTy() || shouldChangeType(Ty,
X->getType())) &&
1464 if (ShAmtC ==
BitWidth - SrcTyBitWidth) {
1466 unsigned NewShAmt = std::min(ShAmtC, SrcTyBitWidth - 1);
1486 return BinaryOperator::CreateAnd(Signbit,
X);
1498 unsigned SrcWidth =
X->getType()->getScalarSizeInBits();
1506 if (AmtSum < SrcWidth &&
1514 return BinaryOperator::CreateAnd(Trunc, ConstantInt::get(Ty, MaskC));
1520 if (
BitWidth > 2 && (*MulC - 1).isPowerOf2() &&
1530 auto *NewAdd = BinaryOperator::CreateNUWAdd(
1533 NewAdd->setHasNoSignedWrap(
1546 if (MulC->
eq(NewMulC.
shl(ShAmtC))) {
1548 BinaryOperator::CreateNUWMul(
X, ConstantInt::get(Ty, NewMulC));
1550 "lshr X, 0 should be handled by simplifyLShrInst.");
1551 NewMul->setHasNoSignedWrap(
true);
1559 if (
BitWidth > 2 && (*MulC - 1).isPowerOf2() &&
1561 return BinaryOperator::CreateNSWAdd(
1572 unsigned SrcWidth =
X->getType()->getScalarSizeInBits();
1573 unsigned WidthDiff =
BitWidth - SrcWidth;
1574 if (SrcWidth % 16 == 0) {
1576 if (ShAmtC >= WidthDiff) {
1583 Constant *ShiftDiff = ConstantInt::get(Ty, WidthDiff - ShAmtC);
1584 return BinaryOperator::CreateShl(NewZExt, ShiftDiff);
1591 Value *BoolX, *BoolY;
1596 (
X->hasOneUse() ||
Y->hasOneUse() || Op0->
hasOneUse())) {
1610 return BinaryOperator::CreateAnd(Mask,
X);
1616 return BinaryOperator::CreateLShr(
AllOnes, Op1);
1623 Value *Shl0_Op0, *Shl0_Op1, *Shl1_Op1;
1626 match(Op1, m_Intrinsic<Intrinsic::cttz>(
m_BinOp(Shl1))) &&
1629 auto *Shl0 = cast<BinaryOperator>(Op0);
1632 if (HasNUW || HasNSW) {
1634 Shl0_Op1,
"", HasNUW, HasNSW);
1635 return BinaryOperator::CreateLShr(NewShl, Shl1_Op1);
1645 "Must be called with arithmetic right-shift instruction only.");
1651 APInt(
C->getType()->getScalarSizeInBits(),
1652 V->getType()->getScalarSizeInBits())));
1660 if (!
match(&OldAShr,
1666 !BitWidthSplat(C1, &OldAShr) || !BitWidthSplat(C2, &OldAShr))
1672 bool HadTrunc = MaybeTrunc != HighBitExtract;
1675 Value *
X, *NumLowBitsToSkip;
1681 if (!
match(NumLowBitsToSkip,
1684 !BitWidthSplat(C0, HighBitExtract))
1721 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1722 Type *Ty =
I.getType();
1724 const APInt *ShAmtAPInt;
1733 ShAmt ==
BitWidth -
X->getType()->getScalarSizeInBits())
1742 if (ShlAmt < ShAmt) {
1744 Constant *ShiftDiff = ConstantInt::get(Ty, ShAmt - ShlAmt);
1745 auto *NewAShr = BinaryOperator::CreateAShr(
X, ShiftDiff);
1746 NewAShr->setIsExact(
I.isExact());
1749 if (ShlAmt > ShAmt) {
1751 Constant *ShiftDiff = ConstantInt::get(Ty, ShlAmt - ShAmt);
1753 NewShl->setHasNoSignedWrap(
true);
1762 AmtSum = std::min(AmtSum,
BitWidth - 1);
1764 return BinaryOperator::CreateAShr(
X, ConstantInt::get(Ty, AmtSum));
1768 (Ty->
isVectorTy() || shouldChangeType(Ty,
X->getType()))) {
1770 Type *SrcTy =
X->getType();
1794 (
BitWidth > 2 && (*MulC - 1).isPowerOf2() &&
1799 auto *NewAdd = BinaryOperator::CreateNSWAdd(
1802 NewAdd->setHasNoUnsignedWrap(
1819 Constant *Mask = ConstantInt::get(Ty, 1);
1823 cast<Constant>(cast<Instruction>(Op0)->getOperand(1)));
1833 Instruction *Lshr = BinaryOperator::CreateLShr(Op0, Op1);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
This file provides internal interfaces used to implement the InstCombine.
static Value * foldShiftedShift(BinaryOperator *InnerShift, unsigned OuterShAmt, bool IsOuterShl, InstCombiner::BuilderTy &Builder)
Fold OuterShift (InnerShift X, C1), C2.
static bool setShiftFlags(BinaryOperator &I, const SimplifyQuery &Q)
static Instruction * dropRedundantMaskingOfLeftShiftInput(BinaryOperator *OuterShift, const SimplifyQuery &Q, InstCombiner::BuilderTy &Builder)
static bool canEvaluateShifted(Value *V, unsigned NumBits, bool IsLeftShift, InstCombinerImpl &IC, Instruction *CxtI)
See if we can compute the specified value, but shifted logically to the left or right by some number ...
bool canTryToConstantAddTwoShiftAmounts(Value *Sh0, Value *ShAmt0, Value *Sh1, Value *ShAmt1)
static Instruction * foldShiftOfShiftedBinOp(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
If we have a shift-by-constant of a bin op (bitwise logic op or add/sub w/ shl) that itself has a shi...
static bool canEvaluateShiftedShift(unsigned OuterShAmt, bool IsOuterShl, Instruction *InnerShift, InstCombinerImpl &IC, Instruction *CxtI)
Return true if we can simplify two logical (either left or right) shifts that have constant shift amo...
static Value * getShiftedValue(Value *V, unsigned NumBits, bool isLeftShift, InstCombinerImpl &IC, const DataLayout &DL)
When canEvaluateShifted() returns true for an expression, this function inserts the new computation t...
static bool canShiftBinOpWithConstantRHS(BinaryOperator &Shift, BinaryOperator *BO)
This file provides the interface for the instcombine pass implementation.
static bool hasNoSignedWrap(BinaryOperator &I)
static bool hasNoUnsignedWrap(BinaryOperator &I)
uint64_t IntrinsicInst * II
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const SmallVectorImpl< MachineOperand > & Cond
static const MCExpr * MaskShift(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
static SymbolRef::Type getType(const Symbol *Sym)
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
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 ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
bool isNegative() const
Determine sign of this APInt.
bool eq(const APInt &RHS) const
Equality comparison.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned logBase2() const
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
APInt shl(unsigned shiftAmt) const
Left-shift function.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
static LLVM_ABI BinaryOperator * CreateNeg(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Helper functions to construct and inspect unary operations (NEG and NOT) via binary operators SUB and...
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.
static LLVM_ABI CastInst * CreateTruncOrBitCast(Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Create a Trunc or BitCast cast instruction.
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 ...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLE
signed less or equal
@ ICMP_ULT
unsigned less than
@ ICMP_SGE
signed greater or equal
static LLVM_ABI Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI Constant * getNot(Constant *C)
static LLVM_ABI Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
This is an important base class in LLVM.
static LLVM_ABI Constant * replaceUndefsWith(Constant *C, Constant *Replacement)
Try to replace undefined constant C or undefined elements in C with Replacement.
static LLVM_ABI Constant * mergeUndefsWith(Constant *C, Constant *Other)
Merges undefs of a Constant with another Constant, along with the undefs already present.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateIsNotNeg(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg > -1.
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
InstTy * Insert(InstTy *I, const Twine &Name="") const
Insert and return the specified instruction.
LLVM_ABI CallInst * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 1 operand which is mangled on its type.
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
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 * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateIsNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg == 0.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Instruction * FoldOpIntoSelect(Instruction &Op, SelectInst *SI, bool FoldWithMultiUse=false)
Given an instruction with a select as one operand and a constant as the other operand,...
Instruction * visitLShr(BinaryOperator &I)
Instruction * foldBinOpIntoSelectOrPhi(BinaryOperator &I)
This is a convenience wrapper function for the above two functions.
Value * reassociateShiftAmtsOfTwoSameDirectionShifts(BinaryOperator *Sh0, const SimplifyQuery &SQ, bool AnalyzeForSignBitExtraction=false)
Instruction * visitAShr(BinaryOperator &I)
Instruction * eraseInstFromFunction(Instruction &I) override
Combiner aware instruction erasure.
Instruction * visitShl(BinaryOperator &I)
Instruction * foldBinopWithPhiOperands(BinaryOperator &BO)
For a binary operator with 2 phi operands, try to hoist the binary operation before the phi.
Instruction * foldVariableSignZeroExtensionOfVariableHighBitExtract(BinaryOperator &OldAShr)
Instruction * commonShiftTransforms(BinaryOperator &I)
bool SimplifyDemandedInstructionBits(Instruction &Inst)
Tries to simplify operands to an integer instruction based on its demanded bits.
Instruction * foldVectorBinop(BinaryOperator &Inst)
Canonicalize the position of binops relative to shufflevector.
Instruction * FoldShiftByConstant(Value *Op0, Constant *Op1, BinaryOperator &I)
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
Instruction * InsertNewInstWith(Instruction *New, BasicBlock::iterator Old)
Same as InsertNewInstBefore, but also sets the debug loc.
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.
bool MaskedValueIsZero(const Value *V, const APInt &Mask, const Instruction *CxtI=nullptr, unsigned Depth=0) const
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, const Instruction *CxtI=nullptr, unsigned Depth=0)
LLVM_ABI void setHasNoUnsignedWrap(bool b=true)
Set or clear the nuw flag on this instruction, which must be an operator which supports this flag.
LLVM_ABI bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap 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 void setHasNoSignedWrap(bool b=true)
Set or clear the nsw 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 bool isExact() const LLVM_READONLY
Determine whether the exact flag is set.
bool isLogicalShift() const
Return true if this is a logical shift left or a logical shift right.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI void setIsExact(bool b=true)
Set or clear the exact flag on this instruction, which must be an operator which supports this flag.
op_range incoming_values()
void setIncomingValue(unsigned i, Value *V)
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
This class represents a sign extension of integer types.
This class represents the LLVM 'select' instruction.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, Instruction *MDFrom=nullptr)
This class represents a truncation of integer types.
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.
LLVM_ABI Type * getExtendedType() const
Given scalar/vector integer type, returns a type with elements twice as wide as in the original type.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
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.
This class represents zero extension of integer types.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
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)
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)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(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)
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
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)
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)
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.
match_combine_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)
Combine two pattern matchers matching L && R.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
deferredval_ty< 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()...
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoSignedWrap > m_NSWShl(const LHS &L, const RHS &R)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWShl(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWMul(const LHS &L, const RHS &R)
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
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.
BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWSub(const LHS &L, const RHS &R)
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
AnyBinaryOp_match< LHS, RHS, true > m_c_BinOp(const LHS &L, const RHS &R)
Matches a BinaryOperator with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
Exact_match< T > m_Exact(const T &SubPattern)
BinOpPred_match< LHS, RHS, is_shift_op > m_Shift(const LHS &L, const RHS &R)
Matches shift operations.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)
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.
match_combine_or< OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap >, DisjointOr_match< LHS, RHS > > m_NUWAddLike(const LHS &L, const RHS &R)
Match either "add nuw" or "or disjoint".
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoSignedWrap > m_NSWMul(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || 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.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI Value * simplifyAShrInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q)
Given operands for a AShr, fold the result or return nulll.
LLVM_ABI Value * simplifySubInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for a Sub, fold the result or return null.
LLVM_ABI Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for an Add, fold the result or return null.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
LLVM_ABI Value * simplifyShlInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for a Shl, fold the result or return null.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
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 Value * simplifyLShrInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q)
Given operands for a LShr, fold the result or return null.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
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 Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
LLVM_ABI unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Return the number of times the sign bit of the register is replicated into the other bits.
constexpr unsigned BitWidth
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
unsigned countMinSignBits() const
Returns the number of times the sign bit is replicated into the other bits.
unsigned countMinTrailingZeros() const
Returns the minimum number of trailing zero bits.
unsigned getBitWidth() const
Get the bit width of this value.
unsigned countMinLeadingZeros() const
Returns the minimum number of leading zero bits.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
SimplifyQuery getWithInstruction(const Instruction *I) const