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.");
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() &&
336 BinInst->getOpcode() != Instruction::Add &&
337 BinInst->getOpcode() != Instruction::Sub) ||
338 !BinInst->hasOneUse())
347 if ((BinInst->getOpcode() == Instruction::Add ||
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();
407 if (isa<Constant>(Op0))
412 if (
Constant *CUI = dyn_cast<Constant>(Op1))
416 if (
auto *NewShift = cast_or_null<Instruction>(
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) {
500 const APInt *InnerShiftConst;
507 bool IsInnerShl = InnerShift->
getOpcode() == Instruction::Shl;
508 if (IsInnerShl == IsOuterShl)
514 if (*InnerShiftConst == OuterShAmt)
524 if (InnerShiftConst->
ugt(OuterShAmt) && InnerShiftConst->
ult(TypeWidth)) {
527 IsInnerShl ? TypeWidth - InnerShAmt : InnerShAmt - OuterShAmt;
549 if (isa<Constant>(V))
553 if (!
I)
return false;
557 if (!
I->hasOneUse())
return false;
559 switch (
I->getOpcode()) {
560 default:
return false;
561 case Instruction::And:
562 case Instruction::Or:
563 case Instruction::Xor:
568 case Instruction::Shl:
569 case Instruction::LShr:
572 case Instruction::Select: {
574 Value *TrueVal =
SI->getTrueValue();
575 Value *FalseVal =
SI->getFalseValue();
579 case Instruction::PHI: {
589 case Instruction::Mul: {
590 const APInt *MulConst;
592 return !IsLeftShift &&
match(
I->getOperand(1),
m_APInt(MulConst)) &&
603 bool IsInnerShl = InnerShift->
getOpcode() == Instruction::Shl;
613 auto NewInnerShift = [&](
unsigned ShAmt) {
627 if (IsInnerShl == IsOuterShl) {
629 if (InnerShAmt + OuterShAmt >= TypeWidth)
632 return NewInnerShift(InnerShAmt + OuterShAmt);
638 if (InnerShAmt == OuterShAmt) {
639 APInt Mask = IsInnerShl
644 if (
auto *AndI = dyn_cast<Instruction>(
And)) {
645 AndI->moveBefore(InnerShift);
646 AndI->takeName(InnerShift);
651 assert(InnerShAmt > OuterShAmt &&
652 "Unexpected opposite direction logical shift pair");
658 return NewInnerShift(InnerShAmt - OuterShAmt);
666 if (
Constant *
C = dyn_cast<Constant>(V)) {
676 switch (
I->getOpcode()) {
678 case Instruction::And:
679 case Instruction::Or:
680 case Instruction::Xor:
688 case Instruction::Shl:
689 case Instruction::LShr:
693 case Instruction::Select:
699 case Instruction::PHI: {
706 isLeftShift, IC,
DL));
709 case Instruction::Mul: {
710 assert(!isLeftShift &&
"Unexpected shift direction!");
713 unsigned TypeWidth =
I->getType()->getScalarSizeInBits();
715 auto *
And = BinaryOperator::CreateAnd(Neg,
730 case Instruction::Add:
731 return Shift.
getOpcode() == Instruction::Shl;
732 case Instruction::Or:
733 case Instruction::And:
735 case Instruction::Xor:
752 bool IsLeftShift =
I.getOpcode() == Instruction::Shl;
753 Type *Ty =
I.getType();
766 auto ExtOpcode = (
I.getOpcode() == Instruction::AShr) ? Instruction::SExt
776 "Shift over the type width should have been removed already");
780 if (
I.getOpcode() != Instruction::AShr &&
783 dbgs() <<
"ICE: GetShiftedValue propagating shift through expression"
784 " to eliminate shift:\n IN: "
785 << *Op0 <<
"\n SH: " <<
I <<
"\n");
797 if (
auto *Op0BO = dyn_cast<BinaryOperator>(Op0)) {
829 if (!isa<Constant>(FalseVal) && TBO->
getOperand(0) == FalseVal &&
846 if (!isa<Constant>(TrueVal) && FBO->
getOperand(0) == TrueVal &&
873 assert(
I.getOpcode() == Instruction::LShr);
876 Value *ShiftAmt =
I.getOperand(1);
877 Type *Ty =
I.getType();
882 const APInt *ShAmtAPInt =
nullptr;
883 Value *
X =
nullptr, *
Y =
nullptr;
894 if (
X->getType()->getScalarSizeInBits() != ShAmt ||
895 Y->getType()->getScalarSizeInBits() != ShAmt)
899 if (!
Add->hasOneUse()) {
904 TruncInst *Trunc = dyn_cast<TruncInst>(U);
922 if (!
Add->hasOneUse()) {
935 I.hasNoSignedWrap(),
I.hasNoUnsignedWrap(), Q))
947 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
948 Type *Ty =
I.getType();
953 unsigned ShAmtC =
C->getZExtValue();
959 unsigned SrcWidth =
X->getType()->getScalarSizeInBits();
960 if (ShAmtC < SrcWidth &&
975 if (ShrAmt < ShAmtC) {
978 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
979 NewShl->setHasNoUnsignedWrap(
I.hasNoUnsignedWrap());
980 NewShl->setHasNoSignedWrap(
I.hasNoSignedWrap());
983 if (ShrAmt > ShAmtC) {
987 cast<BinaryOperator>(Op0)->
getOpcode(),
X, ShiftDiff);
988 NewShr->setIsExact(
true);
996 if (ShrAmt < ShAmtC) {
999 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
1000 NewShl->setHasNoUnsignedWrap(
I.hasNoUnsignedWrap());
1001 NewShl->setHasNoSignedWrap(
I.hasNoSignedWrap());
1006 if (ShrAmt > ShAmtC) {
1009 auto *OldShr = cast<BinaryOperator>(Op0);
1012 NewShr->setIsExact(OldShr->isExact());
1025 unsigned ShDiff = ShrAmtC > ShAmtC ? ShrAmtC - ShAmtC : ShAmtC - ShrAmtC;
1027 auto ShiftOpc = ShrAmtC > ShAmtC ? Shr->
getOpcode() : Instruction::Shl;
1050 switch (BinOpcode) {
1053 case Instruction::Add:
1054 case Instruction::And:
1055 case Instruction::Or:
1056 case Instruction::Xor:
1057 case Instruction::Sub:
1065 isSuitableBinOpcode(Op0BO->
getOpcode())) {
1086 unsigned Op1Val =
C->getLimitedValue(
BitWidth);
1089 return BinaryOperator::CreateAnd(
B, Mask);
1100 X->getName() +
".mask");
1109 return BinaryOperator::CreateSub(NewLHS, NewShift);
1113 if (!
I.hasNoUnsignedWrap() &&
1116 I.setHasNoUnsignedWrap();
1122 I.setHasNoSignedWrap();
1133 return BinaryOperator::CreateAnd(Mask,
X);
1154 return BinaryOperator::CreateLShr(
1162 return BinaryOperator::CreateAnd(NegX,
X);
1168 Constant *ConstantOne = cast<Constant>(Op0);
1170 I.setHasNoUnsignedWrap();
1189 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1190 Type *Ty =
I.getType();
1201 unsigned ShAmtC =
C->getZExtValue();
1202 auto *II = dyn_cast<IntrinsicInst>(Op0);
1204 (II->getIntrinsicID() == Intrinsic::ctlz ||
1205 II->getIntrinsicID() == Intrinsic::cttz ||
1206 II->getIntrinsicID() == Intrinsic::ctpop)) {
1210 bool IsPop = II->getIntrinsicID() == Intrinsic::ctpop;
1219 if (C1->
ult(ShAmtC)) {
1224 auto *NewLShr = BinaryOperator::CreateLShr(
X, ShiftDiff);
1225 NewLShr->setIsExact(
I.isExact());
1234 }
else if (C1->
ugt(ShAmtC)) {
1239 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
1240 NewShl->setHasNoUnsignedWrap(
true);
1266 unsigned Op1Val =
C->getLimitedValue(
BitWidth);
1269 return BinaryOperator::CreateAnd(NewAdd, Mask);
1273 (!Ty->
isIntegerTy() || shouldChangeType(Ty,
X->getType()))) {
1275 "Big shift not simplified to zero?");
1282 unsigned SrcTyBitWidth =
X->getType()->getScalarSizeInBits();
1284 if (SrcTyBitWidth == 1) {
1290 if ((!Ty->
isIntegerTy() || shouldChangeType(Ty,
X->getType())) &&
1300 if (ShAmtC ==
BitWidth - SrcTyBitWidth) {
1302 unsigned NewShAmt = std::min(ShAmtC, SrcTyBitWidth - 1);
1322 return BinaryOperator::CreateAnd(Signbit,
X);
1337 unsigned SrcWidth =
X->getType()->getScalarSizeInBits();
1345 if (AmtSum < SrcWidth &&
1374 if (MulC->
eq(NewMulC.
shl(ShAmtC))) {
1389 unsigned SrcWidth =
X->getType()->getScalarSizeInBits();
1390 unsigned WidthDiff =
BitWidth - SrcWidth;
1391 if (SrcWidth % 16 == 0) {
1393 if (ShAmtC >= WidthDiff) {
1401 return BinaryOperator::CreateShl(NewZExt, ShiftDiff);
1408 Value *BoolX, *BoolY;
1413 (
X->hasOneUse() ||
Y->hasOneUse() || Op0->
hasOneUse())) {
1430 return BinaryOperator::CreateAnd(Mask,
X);
1443 "Must be called with arithmetic right-shift instruction only.");
1449 APInt(
C->getType()->getScalarSizeInBits(),
1450 V->getType()->getScalarSizeInBits())));
1458 if (!
match(&OldAShr,
1464 !BitWidthSplat(C1, &OldAShr) || !BitWidthSplat(C2, &OldAShr))
1470 bool HadTrunc = MaybeTrunc != HighBitExtract;
1473 Value *
X, *NumLowBitsToSkip;
1479 if (!
match(NumLowBitsToSkip,
1482 !BitWidthSplat(C0, HighBitExtract))
1519 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1520 Type *Ty =
I.getType();
1522 const APInt *ShAmtAPInt;
1531 ShAmt ==
BitWidth -
X->getType()->getScalarSizeInBits())
1540 if (ShlAmt < ShAmt) {
1543 auto *NewAShr = BinaryOperator::CreateAShr(
X, ShiftDiff);
1544 NewAShr->setIsExact(
I.isExact());
1547 if (ShlAmt > ShAmt) {
1551 NewShl->setHasNoSignedWrap(
true);
1560 AmtSum = std::min(AmtSum,
BitWidth - 1);
1566 (Ty->
isVectorTy() || shouldChangeType(Ty,
X->getType()))) {
1568 Type *SrcTy =
X->getType();
1604 cast<Constant>(cast<Instruction>(Op0)->getOperand(1)));
1614 Instruction *Lshr = BinaryOperator::CreateLShr(Op0, Op1);
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
SmallVector< MachineOperand, 4 > Cond
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static 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 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 hasNoUnsignedWrap(BinaryOperator &I)
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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
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 BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), Instruction *InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
static BinaryOperator * CreateNeg(Value *Op, const Twine &Name="", Instruction *InsertBefore=nullptr)
Helper functions to construct and inspect unary operations (NEG and NOT) via binary operators SUB and...
BinaryOps getOpcode() const
static BinaryOperator * CreateNot(Value *Op, const Twine &Name="", Instruction *InsertBefore=nullptr)
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 ...
static CastInst * CreateTruncOrBitCast(Value *S, Type *Ty, const Twine &Name="", Instruction *InsertBefore=nullptr)
Create a Trunc or BitCast cast instruction.
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 Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getZExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getNot(Constant *C)
static Constant * getZExtOrBitCast(Constant *C, Type *Ty)
static Constant * getShl(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getLShr(Constant *C1, Constant *C2, bool isExact=false)
static Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
static ConstantInt * 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 Constant * replaceUndefsWith(Constant *C, Constant *Replacement)
Try to replace undefined constant C or undefined elements in C with Replacement.
bool containsUndefElement() const
Return true if this is a vector constant that includes any strictly undef (not poison) elements.
static Constant * mergeUndefsWith(Constant *C, Constant *Other)
Merges undefs of a Constant with another Constant, along with the undefs already present.
static Constant * getAllOnesValue(Type *Ty)
static 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.
CallInst * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with 1 operand which is mangled on its type.
Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
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 * CreateZExt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
InstTy * Insert(InstTy *I, const Twine &Name="") const
Insert and return the specified instruction.
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=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 * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
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 * 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 * InsertNewInstWith(Instruction *New, Instruction &Old)
Same as InsertNewInstBefore, but also sets the debug loc.
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
unsigned ComputeNumSignBits(const Value *Op, unsigned Depth=0, const Instruction *CxtI=nullptr) 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, unsigned Depth=0, const Instruction *CxtI=nullptr) const
void setHasNoUnsignedWrap(bool b=true)
Set or clear the nuw flag on this instruction, which must be an operator which supports this flag.
bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
void copyIRFlags(const Value *V, bool IncludeWrapFlags=true)
Convenience method to copy supported exact, fast-math, and (optionally) wrapping flags from V to this...
void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
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.
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="", Instruction *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.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
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.
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.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
This class represents zero extension of integer types.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
specific_intval< false > m_SpecificInt(APInt V)
Match a specific integer value or vector with all elements equal to the value.
match_combine_or< CastClass_match< OpTy, Instruction::ZExt >, OpTy > m_ZExtOrSelf(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
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)
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power-of-2.
CastClass_match< OpTy, Instruction::SExt > m_SExt(const OpTy &Op)
Matches SExt.
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
CastClass_match< OpTy, Instruction::ZExt > m_ZExt(const OpTy &Op)
Matches ZExt.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWSub(const LHS &L, const RHS &R)
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.
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()...
OneUse_match< T > m_OneUse(const T &SubPattern)
BinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub > m_Neg(const ValTy &V)
Matches a 'Neg' as 'sub 0, V'.
CastClass_match< OpTy, Instruction::Trunc > m_Trunc(const OpTy &Op)
Matches Trunc.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoSignedWrap > m_NSWShl(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWMul(const LHS &L, const RHS &R)
match_combine_or< CastClass_match< OpTy, Instruction::Trunc >, OpTy > m_TruncOrSelf(const OpTy &Op)
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)
specific_intval< true > m_SpecificIntAllowUndef(APInt V)
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< 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'.
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
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.
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.
Value * simplifyAShrInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q)
Given operands for a AShr, fold the result or return nulll.
Value * simplifySubInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for a Sub, fold the result or return null.
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.
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.
Value * simplifyLShrInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q)
Given operands for a LShr, fold the result or return null.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
@ And
Bitwise or logical AND of integers.
constexpr unsigned BitWidth
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
SimplifyQuery getWithInstruction(Instruction *I) const