Go to the documentation of this file.
19 using 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.");
148 if (ShiftOpcode == Instruction::BinaryOps::Shl) {
188 "The input must be 'shl'!");
190 Value *Masked, *ShiftShAmt;
203 bool HadTrunc = WidestTy != NarrowestTy;
235 MaskShAmt, ShiftShAmt,
false,
false, Q));
251 auto *ExtendedInvertedMask =
267 ShiftShAmt, MaskShAmt,
false,
false, Q));
332 assert(
I.isShift() &&
"Expected a shift as input");
333 auto *BinInst = dyn_cast<BinaryOperator>(
I.getOperand(0));
335 (!BinInst->isBitwiseLogicOp() &&
337 BinInst->getOpcode() != Instruction::Sub) ||
338 !BinInst->hasOneUse())
348 BinInst->getOpcode() == Instruction::Sub) &&
349 ShiftOpcode != Instruction::Shl)
352 Type *Ty =
I.getType();
358 auto matchFirstShift = [&](
Value *V) {
369 bool FirstShiftIsOp1 =
false;
370 if (matchFirstShift(BinInst->getOperand(0)))
371 Y = BinInst->getOperand(1);
372 else if (matchFirstShift(BinInst->getOperand(1))) {
373 Y = BinInst->getOperand(0);
374 FirstShiftIsOp1 = BinInst->getOpcode() == Instruction::Sub;
380 Value *NewShift1 =
Builder.CreateBinOp(ShiftOpcode,
X, ShiftSumC);
382 Value *Op1 = FirstShiftIsOp1 ? NewShift2 : NewShift1;
383 Value *Op2 = FirstShiftIsOp1 ? NewShift1 : NewShift2;
391 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
393 Type *Ty =
I.getType();
403 if (SimplifyDemandedInstructionBits(
I))
407 if (isa<Constant>(Op0))
412 if (
Constant *CUI = dyn_cast<Constant>(Op1))
413 if (
Instruction *Res = FoldShiftByConstant(Op0, CUI,
I))
416 if (
auto *NewShift = cast_or_null<Instruction>(
417 reassociateShiftAmtsOfTwoSameDirectionShifts(&
I, SQ)))
432 const APInt *AC, *AddC;
440 assert(!AC->
isZero() &&
"Expected simplify of shifted zero");
441 unsigned PosOffset = (-*AddC).getZExtValue();
443 auto isSuitableForPreShift = [PosOffset, &
I, AC]() {
444 switch (
I.getOpcode()) {
447 case Instruction::Shl:
448 return (
I.hasNoSignedWrap() ||
I.hasNoUnsignedWrap()) &&
449 AC->
eq(AC->
lshr(PosOffset).
shl(PosOffset));
450 case Instruction::LShr:
451 return I.isExact() && AC->
eq(AC->
shl(PosOffset).
lshr(PosOffset));
452 case Instruction::AShr:
453 return I.isExact() && AC->
eq(AC->
shl(PosOffset).
ashr(PosOffset));
456 if (isSuitableForPreShift()) {
458 ? AC->
lshr(PosOffset)
459 : AC->
shl(PosOffset));
462 if (
I.getOpcode() == Instruction::Shl) {
480 return replaceOperand(
I, 1, Rem);
497 const APInt *InnerShiftConst;
504 bool IsInnerShl = InnerShift->
getOpcode() == Instruction::Shl;
505 if (IsInnerShl == IsOuterShl)
511 if (*InnerShiftConst == OuterShAmt)
521 if (InnerShiftConst->
ugt(OuterShAmt) && InnerShiftConst->
ult(TypeWidth)) {
524 IsInnerShl ? TypeWidth - InnerShAmt : InnerShAmt - OuterShAmt;
546 if (isa<Constant>(V))
550 if (!
I)
return false;
554 if (!
I->hasOneUse())
return false;
556 switch (
I->getOpcode()) {
557 default:
return false;
558 case Instruction::And:
559 case Instruction::Or:
560 case Instruction::Xor:
565 case Instruction::Shl:
566 case Instruction::LShr:
587 const APInt *MulConst;
589 return !IsLeftShift &&
match(
I->getOperand(1),
m_APInt(MulConst)) &&
601 bool IsInnerShl = InnerShift->
getOpcode() == Instruction::Shl;
608 unsigned InnerShAmt =
C1->getZExtValue();
611 auto NewInnerShift = [&](
unsigned ShAmt) {
625 if (IsInnerShl == IsOuterShl) {
627 if (InnerShAmt + OuterShAmt >= TypeWidth)
630 return NewInnerShift(InnerShAmt + OuterShAmt);
636 if (InnerShAmt == OuterShAmt) {
642 if (
auto *AndI = dyn_cast<Instruction>(
And)) {
643 AndI->moveBefore(InnerShift);
644 AndI->takeName(InnerShift);
649 assert(InnerShAmt > OuterShAmt &&
650 "Unexpected opposite direction logical shift pair");
656 return NewInnerShift(InnerShAmt - OuterShAmt);
664 if (
Constant *
C = dyn_cast<Constant>(V)) {
674 switch (
I->getOpcode()) {
676 case Instruction::And:
677 case Instruction::Or:
678 case Instruction::Xor:
686 case Instruction::Shl:
687 case Instruction::LShr:
704 isLeftShift, IC,
DL));
708 assert(!isLeftShift &&
"Unexpected shift direction!");
711 unsigned TypeWidth =
I->getType()->getScalarSizeInBits();
713 auto *
And = BinaryOperator::CreateAnd(Neg,
729 return Shift.getOpcode() == Instruction::Shl;
730 case Instruction::Or:
731 case Instruction::And:
733 case Instruction::Xor:
748 I.getOpcode(),
Builder.CreateBinOp(
I.getOpcode(), C2,
C1),
X);
750 bool IsLeftShift =
I.getOpcode() == Instruction::Shl;
751 Type *Ty =
I.getType();
764 auto ExtOpcode = (
I.getOpcode() == Instruction::AShr) ? Instruction::SExt
774 "Shift over the type width should have been removed already");
778 if (
I.getOpcode() != Instruction::AShr &&
781 dbgs() <<
"ICE: GetShiftedValue propagating shift through expression"
782 " to eliminate shift:\n IN: "
783 << *Op0 <<
"\n SH: " <<
I <<
"\n");
785 return replaceInstUsesWith(
789 if (
Instruction *FoldedShift = foldBinOpIntoSelectOrPhi(
I))
795 if (
auto *Op0BO = dyn_cast<BinaryOperator>(Op0)) {
802 Builder.CreateBinOp(
I.getOpcode(), Op0BO->getOperand(1),
C1);
805 Builder.CreateBinOp(
I.getOpcode(), Op0BO->getOperand(0),
C1);
871 assert(
I.getOpcode() == Instruction::LShr);
873 Value *Add =
I.getOperand(0);
874 Value *ShiftAmt =
I.getOperand(1);
875 Type *Ty =
I.getType();
880 const APInt *ShAmtAPInt =
nullptr;
881 Value *
X =
nullptr, *
Y =
nullptr;
892 if (
X->getType()->getScalarSizeInBits() != ShAmt ||
893 Y->getType()->getScalarSizeInBits() != ShAmt)
897 if (!Add->hasOneUse()) {
898 for (
User *U : Add->users()) {
902 TruncInst *Trunc = dyn_cast<TruncInst>(U);
911 Builder.SetInsertPoint(AddInst);
915 Builder.CreateICmpULT(NarrowAdd,
X,
"add.narrowed.overflow");
920 if (!
Add->hasOneUse())
921 replaceInstUsesWith(*AddInst,
Builder.CreateZExt(NarrowAdd, Ty));
931 I.hasNoSignedWrap(),
I.hasNoUnsignedWrap(), Q))
932 return replaceInstUsesWith(
I, V);
943 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
944 Type *Ty =
I.getType();
949 unsigned ShAmtC =
C->getZExtValue();
955 unsigned SrcWidth =
X->getType()->getScalarSizeInBits();
956 if (ShAmtC < SrcWidth &&
970 unsigned ShrAmt =
C1->getZExtValue();
971 if (ShrAmt < ShAmtC) {
974 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
975 NewShl->setHasNoUnsignedWrap(
I.hasNoUnsignedWrap());
976 NewShl->setHasNoSignedWrap(
I.hasNoSignedWrap());
979 if (ShrAmt > ShAmtC) {
983 cast<BinaryOperator>(Op0)->
getOpcode(),
X, ShiftDiff);
984 NewShr->setIsExact(
true);
991 unsigned ShrAmt =
C1->getZExtValue();
992 if (ShrAmt < ShAmtC) {
995 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
996 NewShl->setHasNoUnsignedWrap(
I.hasNoUnsignedWrap());
997 NewShl->setHasNoSignedWrap(
I.hasNoSignedWrap());
1002 if (ShrAmt > ShAmtC) {
1005 auto *OldShr = cast<BinaryOperator>(Op0);
1008 NewShr->setIsExact(OldShr->isExact());
1020 unsigned ShrAmtC =
C1->getZExtValue();
1021 unsigned ShDiff = ShrAmtC > ShAmtC ? ShrAmtC - ShAmtC : ShAmtC - ShrAmtC;
1030 Value *Trunc =
Builder.CreateTrunc(NewShift, Ty,
"tr.sh.diff");
1036 unsigned AmtSum = ShAmtC +
C1->getZExtValue();
1046 switch (BinOpcode) {
1050 case Instruction::And:
1051 case Instruction::Or:
1052 case Instruction::Xor:
1053 case Instruction::Sub:
1061 isSuitableBinOpcode(Op0BO->
getOpcode())) {
1082 unsigned Op1Val =
C->getLimitedValue(
BitWidth);
1085 return BinaryOperator::CreateAnd(
B,
Mask);
1096 X->getName() +
".mask");
1105 return BinaryOperator::CreateSub(NewLHS, NewShift);
1109 if (!
I.hasNoUnsignedWrap() &&
1112 I.setHasNoUnsignedWrap();
1118 I.setHasNoSignedWrap();
1129 return BinaryOperator::CreateAnd(
Mask,
X);
1150 return BinaryOperator::CreateLShr(
1156 Constant *ConstantOne = cast<Constant>(Op0);
1158 I.setHasNoUnsignedWrap();
1168 SQ.getWithInstruction(&
I)))
1169 return replaceInstUsesWith(
I, V);
1177 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1178 Type *Ty =
I.getType();
1189 unsigned ShAmtC =
C->getZExtValue();
1190 auto *II = dyn_cast<IntrinsicInst>(Op0);
1192 (II->getIntrinsicID() == Intrinsic::ctlz ||
1193 II->getIntrinsicID() == Intrinsic::cttz ||
1194 II->getIntrinsicID() == Intrinsic::ctpop)) {
1198 bool IsPop = II->getIntrinsicID() == Intrinsic::ctpop;
1207 if (
C1->ult(ShAmtC)) {
1208 unsigned ShlAmtC =
C1->getZExtValue();
1212 auto *NewLShr = BinaryOperator::CreateLShr(
X, ShiftDiff);
1213 NewLShr->setIsExact(
I.isExact());
1218 Value *NewLShr =
Builder.CreateLShr(
X, ShiftDiff,
"",
I.isExact());
1222 }
else if (
C1->ugt(ShAmtC)) {
1223 unsigned ShlAmtC =
C1->getZExtValue();
1227 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
1228 NewShl->setHasNoUnsignedWrap(
true);
1254 unsigned Op1Val =
C->getLimitedValue(
BitWidth);
1257 return BinaryOperator::CreateAnd(NewAdd,
Mask);
1261 (!Ty->
isIntegerTy() || shouldChangeType(Ty,
X->getType()))) {
1263 "Big shift not simplified to zero?");
1270 unsigned SrcTyBitWidth =
X->getType()->getScalarSizeInBits();
1272 if (SrcTyBitWidth == 1) {
1278 if ((!Ty->
isIntegerTy() || shouldChangeType(Ty,
X->getType())) &&
1288 if (ShAmtC ==
BitWidth - SrcTyBitWidth) {
1290 unsigned NewShAmt =
std::min(ShAmtC, SrcTyBitWidth - 1);
1310 return BinaryOperator::CreateAnd(Signbit,
X);
1317 unsigned AmtSum = ShAmtC +
C1->getZExtValue();
1325 unsigned SrcWidth =
X->getType()->getScalarSizeInBits();
1326 unsigned AmtSum = ShAmtC +
C1->getZExtValue();
1333 if (AmtSum < SrcWidth &&
1335 Value *SumShift =
Builder.CreateLShr(
X, AmtSum,
"sum.shift");
1336 Value *Trunc =
Builder.CreateTrunc(SumShift, Ty,
I.getName());
1362 if (MulC->
eq(NewMulC.
shl(ShAmtC))) {
1377 unsigned SrcWidth =
X->getType()->getScalarSizeInBits();
1378 unsigned WidthDiff =
BitWidth - SrcWidth;
1379 if (SrcWidth % 16 == 0) {
1380 Value *NarrowSwap =
Builder.CreateUnaryIntrinsic(Intrinsic::bswap,
X);
1381 if (ShAmtC >= WidthDiff) {
1383 Value *NewShift =
Builder.CreateLShr(NarrowSwap, ShAmtC - WidthDiff);
1389 return BinaryOperator::CreateShl(NewZExt, ShiftDiff);
1396 Value *BoolX, *BoolY;
1401 (
X->hasOneUse() ||
Y->hasOneUse() || Op0->
hasOneUse())) {
1418 return BinaryOperator::CreateAnd(
Mask,
X);
1431 "Must be called with arithmetic right-shift instruction only.");
1437 APInt(
C->getType()->getScalarSizeInBits(),
1438 V->getType()->getScalarSizeInBits())));
1446 if (!
match(&OldAShr,
1452 !BitWidthSplat(
C1, &OldAShr) || !BitWidthSplat(C2, &OldAShr))
1458 bool HadTrunc = MaybeTrunc != HighBitExtract;
1461 Value *
X, *NumLowBitsToSkip;
1467 if (!
match(NumLowBitsToSkip,
1470 !BitWidthSplat(C0, HighBitExtract))
1477 return replaceInstUsesWith(OldAShr, MaybeTrunc);
1498 SQ.getWithInstruction(&
I)))
1499 return replaceInstUsesWith(
I, V);
1507 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1508 Type *Ty =
I.getType();
1510 const APInt *ShAmtAPInt;
1519 ShAmt ==
BitWidth -
X->getType()->getScalarSizeInBits())
1528 if (ShlAmt < ShAmt) {
1531 auto *NewAShr = BinaryOperator::CreateAShr(
X, ShiftDiff);
1532 NewAShr->setIsExact(
I.isExact());
1535 if (ShlAmt > ShAmt) {
1539 NewShl->setHasNoSignedWrap(
true);
1554 (Ty->
isVectorTy() || shouldChangeType(Ty,
X->getType()))) {
1556 Type *SrcTy =
X->getType();
1592 cast<Constant>(cast<Instruction>(Op0)->getOperand(1)));
1597 if (
Instruction *R = foldVariableSignZeroExtensionOfVariableHighBitExtract(
I))
1602 Instruction *Lshr = BinaryOperator::CreateLShr(Op0, Op1);
This is an optimization pass for GlobalISel generic memory operations.
Value * simplifyAShrInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q)
Given operands for a AShr, fold the result or return nulll.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
match_combine_or< CastClass_match< OpTy, Instruction::Trunc >, OpTy > m_TruncOrSelf(const OpTy &Op)
static Constant * getNot(Constant *C)
bool MaskedValueIsZero(const Value *V, const APInt &Mask, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return true if 'V & Mask' is known to be zero.
op_range incoming_values()
A parsed version of the target data layout string in and methods for querying it.
static Constant * getZExtOrBitCast(Constant *C, Type *Ty)
bool hasOneUse() const
Return true if there is exactly one use of this value.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
bool canTryToConstantAddTwoShiftAmounts(Value *Sh0, Value *ShAmt0, Value *Sh1, Value *ShAmt1)
static Constant * getZExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Instruction * FoldShiftByConstant(Value *Op0, Constant *Op1, BinaryOperator &I)
static BinaryOperator * CreateNot(Value *Op, const Twine &Name="", Instruction *InsertBefore=nullptr)
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
instcombine should handle this C2 when C1
static bool canShiftBinOpWithConstantRHS(BinaryOperator &Shift, BinaryOperator *BO)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(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.
static CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", Instruction *InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
The instances of the Type class are immutable: once they are created, they are never changed.
Value * reassociateShiftAmtsOfTwoSameDirectionShifts(BinaryOperator *Sh0, const SimplifyQuery &SQ, bool AnalyzeForSignBitExtraction=false)
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...
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
void setHasNoUnsignedWrap(bool b=true)
Set or clear the nuw flag on this instruction, which must be an operator which supports this flag.
bool containsUndefElement() const
Return true if this is a vector constant that includes any strictly undef (not poison) elements.
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)
unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return the number of times the sign bit of the register is replicated into the other bits.
void addToWorklist(Instruction *I)
@ ICMP_SLE
signed less or equal
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
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.
NUW NUW NUW NUW Exact static Exact BinaryOperator * CreateNeg(Value *Op, const Twine &Name="", Instruction *InsertBefore=nullptr)
Helper functions to construct and inspect unary operations (NEG and NOT) via binary operators SUB and...
void setIsExact(bool b=true)
Set or clear the exact flag on this instruction, which must be an operator which supports this flag.
void setIncomingValue(unsigned i, Value *V)
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()...
OneUse_match< T > m_OneUse(const T &SubPattern)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
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.
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
AnyBinaryOp_match< LHS, RHS, true > m_c_BinOp(const LHS &L, const RHS &R)
Matches a BinaryOperator with LHS and RHS in either order.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
bool isNegative() const
Determine sign of this APInt.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", Instruction *InsertBefore=nullptr, Instruction *MDFrom=nullptr)
Instruction * foldVariableSignZeroExtensionOfVariableHighBitExtract(BinaryOperator &OldAShr)
@ And
Bitwise or logical AND of integers.
static bool hasNoUnsignedWrap(BinaryOperator &I)
bool eq(const APInt &RHS) const
Equality comparison.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
bool match(Val *V, const Pattern &P)
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
Exact_match< T > m_Exact(const T &SubPattern)
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...
specific_intval< true > m_SpecificIntAllowUndef(APInt V)
(vector float) vec_cmpeq(*A, *B) C
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
bool isVectorTy() const
True if this is an instance of VectorType.
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
CastClass_match< OpTy, Instruction::ZExt > m_ZExt(const OpTy &Op)
Matches ZExt.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
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.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static Constant * getAllOnesValue(Type *Ty)
BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)
BinaryOps getOpcode() const
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
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.
uint64_t getZExtValue() const
Get zero extended value.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWSub(const LHS &L, const RHS &R)
unsigned countTrailingZeros() const
Count the number of trailing zero bits.
static CastInst * CreateTruncOrBitCast(Value *S, Type *Ty, const Twine &Name="", Instruction *InsertBefore=nullptr)
Create a Trunc or BitCast cast instruction.
BinOpPred_match< LHS, RHS, is_shift_op > m_Shift(const LHS &L, const RHS &R)
Matches shift operations.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power-of-2.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
Type * getExtendedType() const
Given scalar/vector integer type, returns a type with elements twice as wide as in the original type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
match_combine_or< CastClass_match< OpTy, Instruction::ZExt >, OpTy > m_ZExtOrSelf(const OpTy &Op)
static Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWAdd(const LHS &L, const RHS &R)
Instruction * visitShl(BinaryOperator &I)
This is an important base class in LLVM.
bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
bool isLogicalShift() const
Return true if this is a logical shift left or a logical shift right.
static Constant * replaceUndefsWith(Constant *C, Constant *Replacement)
Try to replace undefined constant C or undefined elements in C with Replacement.
bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
This class represents a truncation of integer types.
unsigned logBase2() const
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
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 Constant * getShl(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This class represents the LLVM 'select' instruction.
SimplifyQuery getWithInstruction(Instruction *I) const
Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for an Add, fold the result or return null.
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
This class represents zero extension of integer types.
Class for arbitrary precision integers.
void setOperand(unsigned i, Value *Val)
static M68kRelType getType(unsigned Kind, MCSymbolRefExpr::VariantKind &Modifier, bool &IsPCRel)
CastClass_match< OpTy, Instruction::SExt > m_SExt(const OpTy &Op)
Matches SExt.
Instruction * visitLShr(BinaryOperator &I)
specific_intval< false > m_SpecificInt(APInt V)
Match a specific integer value or vector with all elements equal to the value.
match_combine_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)
Combine two pattern matchers matching L && R.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWMul(const LHS &L, const RHS &R)
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
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.
SmallVector< MachineOperand, 4 > Cond
@ ICMP_ULT
unsigned less than
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Type * getType() const
All values are typed, get the type of this value.
bool MaskedValueIsZero(const Value *V, const APInt &Mask, unsigned Depth=0, const Instruction *CxtI=nullptr) const
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Value * simplifyLShrInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q)
Given operands for a LShr, fold the result or return null.
static Value * foldShiftedShift(BinaryOperator *InnerShift, unsigned OuterShAmt, bool IsOuterShl, InstCombiner::BuilderTy &Builder)
Fold OuterShift (InnerShift X, C1), C2.
Instruction * InsertNewInstWith(Instruction *New, Instruction &Old)
Same as InsertNewInstBefore, but also sets the debug loc.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
This class represents a sign extension of integer types.
StringRef getName() const
Return a constant reference to the value's name.
Instruction * visitAShr(BinaryOperator &I)
Value * simplifyShlInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for a Shl, fold the result or return null.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
bool isMinSignedValue() const
Determine if this is the smallest signed value.
Instruction * commonShiftTransforms(BinaryOperator &I)
static Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
constexpr unsigned BitWidth
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoSignedWrap > m_NSWShl(const LHS &L, const RHS &R)
static Instruction * dropRedundantMaskingOfLeftShiftInput(BinaryOperator *OuterShift, const SimplifyQuery &Q, InstCombiner::BuilderTy &Builder)
static Constant * getLShr(Constant *C1, Constant *C2, bool isExact=false)
@ ICMP_SGE
signed greater or equal
static Constant * mergeUndefsWith(Constant *C, Constant *Other)
Merges undefs of a Constant with another Constant, along with the undefs already present.
BinaryOp_match< cst_pred_ty< is_all_ones >, ValTy, Instruction::Xor, true > m_Not(const ValTy &V)
Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
static BinaryOperator * CreateMul(Value *S1, Value *S2, const Twine &Name, Instruction *InsertBefore, Value *FlagsOp)
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
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 ...
void copyIRFlags(const Value *V, bool IncludeWrapFlags=true)
Convenience method to copy supported exact, fast-math, and (optionally) wrapping flags from V to this...
BinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub > m_Neg(const ValTy &V)
Matches a 'Neg' as 'sub 0, V'.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
void takeName(Value *V)
Transfer the name from V to this value.
APInt shl(unsigned shiftAmt) const
Left-shift function.
Value * getOperand(unsigned i) const
CastClass_match< OpTy, Instruction::Trunc > m_Trunc(const OpTy &Op)
Matches Trunc.
static BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), Instruction *InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
bool isExact() const LLVM_READONLY
Determine whether the exact flag is set.
LLVM Value Representation.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
Value * simplifySubInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for a Sub, fold the result or return null.