Go to the documentation of this file.
20 using namespace PatternMatch;
22 #define DEBUG_TYPE "instcombine"
40 unsigned MaximalPossibleTotalShiftAmount =
43 APInt MaximalRepresentableShiftAmount =
45 return MaximalRepresentableShiftAmount.
uge(MaximalPossibleTotalShiftAmount);
61 bool AnalyzeForSignBitExtraction) {
73 Value *Trunc =
nullptr;
92 if (AnalyzeForSignBitExtraction && !HadTwoRightShifts)
99 if (!IdenticalShOpcodes && !AnalyzeForSignBitExtraction)
105 if (Trunc && !AnalyzeForSignBitExtraction &&
110 auto *NewShAmt = dyn_cast_or_null<Constant>(
115 unsigned NewShAmtBitWidth = NewShAmt->getType()->getScalarSizeInBits();
116 unsigned XBitWidth =
X->getType()->getScalarSizeInBits();
119 APInt(NewShAmtBitWidth, XBitWidth))))
127 if (HadTwoRightShifts && (Trunc || AnalyzeForSignBitExtraction)) {
131 APInt(NewShAmtBitWidth, XBitWidth - 1))))
134 if (AnalyzeForSignBitExtraction)
138 assert(IdenticalShOpcodes &&
"Should not get here with different shifts.");
149 if (ShiftOpcode == Instruction::BinaryOps::Shl) {
189 "The input must be 'shl'!");
191 Value *Masked, *ShiftShAmt;
204 bool HadTrunc = WidestTy != NarrowestTy;
236 MaskShAmt, ShiftShAmt,
false,
false, Q));
252 auto *ExtendedInvertedMask =
268 ShiftShAmt, MaskShAmt,
false,
false, Q));
332 assert(
I.isShift() &&
"Expected a shift as input");
333 auto *LogicInst = dyn_cast<BinaryOperator>(
I.getOperand(0));
334 if (!LogicInst || !LogicInst->isBitwiseLogicOp() || !LogicInst->hasOneUse())
342 Type *Ty =
I.getType();
348 auto matchFirstShift = [&](
Value *V) {
358 if (matchFirstShift(LogicInst->getOperand(0)))
359 Y = LogicInst->getOperand(1);
360 else if (matchFirstShift(LogicInst->getOperand(1)))
361 Y = LogicInst->getOperand(0);
367 Value *NewShift1 =
Builder.CreateBinOp(ShiftOpcode,
X, ShiftSumC);
368 Value *NewShift2 =
Builder.CreateBinOp(ShiftOpcode,
Y,
I.getOperand(1));
373 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
379 Value *NewExt =
Builder.CreateZExt(
Y,
I.getType(), Op1->getName());
384 if (SimplifyDemandedInstructionBits(
I))
388 if (isa<Constant>(Op0))
393 if (
Constant *CUI = dyn_cast<Constant>(Op1))
394 if (
Instruction *Res = FoldShiftByConstant(Op0, CUI,
I))
397 if (
auto *NewShift = cast_or_null<Instruction>(
398 reassociateShiftAmtsOfTwoSameDirectionShifts(&
I, SQ)))
409 I.getOpcode(),
Builder.CreateBinOp(
I.getOpcode(), Op0,
C), A);
420 return replaceOperand(
I, 1, Rem);
437 const APInt *InnerShiftConst;
444 bool IsInnerShl = InnerShift->
getOpcode() == Instruction::Shl;
445 if (IsInnerShl == IsOuterShl)
451 if (*InnerShiftConst == OuterShAmt)
461 if (InnerShiftConst->
ugt(OuterShAmt) && InnerShiftConst->
ult(TypeWidth)) {
464 IsInnerShl ? TypeWidth - InnerShAmt : InnerShAmt - OuterShAmt;
486 if (isa<Constant>(V))
490 if (!
I)
return false;
494 if (!
I->hasOneUse())
return false;
496 switch (
I->getOpcode()) {
497 default:
return false;
498 case Instruction::And:
499 case Instruction::Or:
500 case Instruction::Xor:
505 case Instruction::Shl:
506 case Instruction::LShr:
516 case Instruction::PHI: {
534 bool IsInnerShl = InnerShift->
getOpcode() == Instruction::Shl;
541 unsigned InnerShAmt =
C1->getZExtValue();
544 auto NewInnerShift = [&](
unsigned ShAmt) {
558 if (IsInnerShl == IsOuterShl) {
560 if (InnerShAmt + OuterShAmt >= TypeWidth)
563 return NewInnerShift(InnerShAmt + OuterShAmt);
569 if (InnerShAmt == OuterShAmt) {
575 if (
auto *AndI = dyn_cast<Instruction>(
And)) {
576 AndI->moveBefore(InnerShift);
577 AndI->takeName(InnerShift);
582 assert(InnerShAmt > OuterShAmt &&
583 "Unexpected opposite direction logical shift pair");
589 return NewInnerShift(InnerShAmt - OuterShAmt);
597 if (
Constant *
C = dyn_cast<Constant>(V)) {
607 switch (
I->getOpcode()) {
609 case Instruction::And:
610 case Instruction::Or:
611 case Instruction::Xor:
619 case Instruction::Shl:
620 case Instruction::LShr:
630 case Instruction::PHI: {
637 isLeftShift, IC,
DL));
651 return Shift.getOpcode() == Instruction::Shl;
652 case Instruction::Or:
653 case Instruction::And:
655 case Instruction::Xor:
664 bool isLeftShift =
I.getOpcode() == Instruction::Shl;
672 if (
I.getOpcode() != Instruction::AShr &&
675 dbgs() <<
"ICE: GetShiftedValue propagating shift through expression"
676 " to eliminate shift:\n IN: "
677 << *Op0 <<
"\n SH: " <<
I <<
"\n");
679 return replaceInstUsesWith(
685 Type *Ty =
I.getType();
688 "Shift over the type width should have been removed already");
690 if (
Instruction *FoldedShift = foldBinOpIntoSelectOrPhi(
I))
694 if (
auto *TI = dyn_cast<TruncInst>(Op0)) {
700 const APInt *TrShiftAmt;
701 if (
I.isLogicalShift() &&
703 auto *TrOp = cast<Instruction>(TI->getOperand(0));
704 Type *SrcTy = TrOp->getType();
709 Value *NSh =
Builder.CreateBinOp(
I.getOpcode(), TrOp, ShAmt,
I.getName());
736 switch (Op0BO->getOpcode()) {
739 case Instruction::And:
740 case Instruction::Or:
741 case Instruction::Xor: {
744 if (isLeftShift && Op0BO->getOperand(1)->hasOneUse() &&
751 Op0BO->getOperand(1)->
getName());
755 return BinaryOperator::CreateAnd(
X,
Mask);
759 Value *Op0BOOp1 = Op0BO->getOperand(1);
760 if (isLeftShift && Op0BOOp1->
hasOneUse() &&
774 case Instruction::Sub: {
776 if (isLeftShift && Op0BO->getOperand(0)->hasOneUse() &&
783 Op0BO->getOperand(0)->
getName());
787 return BinaryOperator::CreateAnd(
X,
Mask);
791 if (isLeftShift && Op0BO->getOperand(0)->hasOneUse() &&
792 match(Op0BO->getOperand(0),
814 cast<Constant>(Op0BO->getOperand(1)), Op1);
817 Builder.CreateBinOp(
I.getOpcode(), Op0BO->getOperand(0), Op1);
828 if (isLeftShift && Op0BO->getOpcode() == Instruction::Sub &&
831 cast<Constant>(Op0BO->getOperand(0)), Op1);
833 Value *NewShift =
Builder.CreateShl(Op0BO->getOperand(1), Op1);
836 return BinaryOperator::CreateSub(NewRHS, NewShift);
895 I.hasNoSignedWrap(),
I.hasNoUnsignedWrap(), Q))
896 return replaceInstUsesWith(
I, V);
907 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
908 Type *Ty =
I.getType();
911 const APInt *ShAmtAPInt;
919 unsigned SrcWidth =
X->getType()->getScalarSizeInBits();
920 if (ShAmt < SrcWidth &&
935 if (ShrAmt < ShAmt) {
938 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
939 NewShl->setHasNoUnsignedWrap(
I.hasNoUnsignedWrap());
940 NewShl->setHasNoSignedWrap(
I.hasNoSignedWrap());
943 if (ShrAmt > ShAmt) {
947 cast<BinaryOperator>(Op0)->
getOpcode(),
X, ShiftDiff);
948 NewShr->setIsExact(
true);
956 if (ShrAmt < ShAmt) {
959 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
960 NewShl->setHasNoUnsignedWrap(
I.hasNoUnsignedWrap());
961 NewShl->setHasNoSignedWrap(
I.hasNoSignedWrap());
966 if (ShrAmt > ShAmt) {
969 auto *OldShr = cast<BinaryOperator>(Op0);
972 NewShr->setIsExact(OldShr->isExact());
988 if (!
I.hasNoUnsignedWrap() &&
990 I.setHasNoUnsignedWrap();
996 I.setHasNoSignedWrap();
1007 return BinaryOperator::CreateAnd(
Mask,
X);
1032 return BinaryOperator::CreateLShr(
1040 SQ.getWithInstruction(&
I)))
1041 return replaceInstUsesWith(
I, V);
1049 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1050 Type *Ty =
I.getType();
1051 const APInt *ShAmtAPInt;
1055 auto *II = dyn_cast<IntrinsicInst>(Op0);
1057 (II->getIntrinsicID() == Intrinsic::ctlz ||
1058 II->getIntrinsicID() == Intrinsic::cttz ||
1059 II->getIntrinsicID() == Intrinsic::ctpop)) {
1063 bool IsPop = II->getIntrinsicID() == Intrinsic::ctpop;
1065 Value *Cmp =
Builder.CreateICmpEQ(II->getArgOperand(0), RHS);
1072 if (ShOp1->
ult(ShAmt)) {
1077 auto *NewLShr = BinaryOperator::CreateLShr(
X, ShiftDiff);
1078 NewLShr->setIsExact(
I.isExact());
1082 Value *NewLShr =
Builder.CreateLShr(
X, ShiftDiff,
"",
I.isExact());
1086 if (ShOp1->
ugt(ShAmt)) {
1091 auto *NewShl = BinaryOperator::CreateShl(
X, ShiftDiff);
1092 NewShl->setHasNoUnsignedWrap(
true);
1107 (!Ty->
isIntegerTy() || shouldChangeType(Ty,
X->getType()))) {
1109 "Big shift not simplified to zero?");
1116 (!Ty->
isIntegerTy() || shouldChangeType(Ty,
X->getType()))) {
1118 unsigned SrcTyBitWidth =
X->getType()->getScalarSizeInBits();
1121 if (SrcTyBitWidth == 1)
1134 unsigned NewShAmt =
std::min(ShAmt, SrcTyBitWidth - 1);
1160 ShAmt * 2 ==
BitWidth && (*MulC - 1).isPowerOf2() &&
1177 return BinaryOperator::CreateAnd(
Mask,
X);
1187 "Must be called with arithmetic right-shift instruction only.");
1193 APInt(
C->getType()->getScalarSizeInBits(),
1194 V->getType()->getScalarSizeInBits())));
1202 if (!
match(&OldAShr,
1208 !BitWidthSplat(
C1, &OldAShr) || !BitWidthSplat(C2, &OldAShr))
1214 bool HadTrunc = MaybeTrunc != HighBitExtract;
1217 Value *
X, *NumLowBitsToSkip;
1223 if (!
match(NumLowBitsToSkip,
1226 !BitWidthSplat(C0, HighBitExtract))
1233 return replaceInstUsesWith(OldAShr, MaybeTrunc);
1254 SQ.getWithInstruction(&
I)))
1255 return replaceInstUsesWith(
I, V);
1263 Value *Op0 =
I.getOperand(0), *Op1 =
I.getOperand(1);
1264 Type *Ty =
I.getType();
1266 const APInt *ShAmtAPInt;
1275 ShAmt ==
BitWidth -
X->getType()->getScalarSizeInBits())
1284 if (ShlAmt < ShAmt) {
1287 auto *NewAShr = BinaryOperator::CreateAShr(
X, ShiftDiff);
1288 NewAShr->setIsExact(
I.isExact());
1291 if (ShlAmt > ShAmt) {
1295 NewShl->setHasNoSignedWrap(
true);
1310 (Ty->
isVectorTy() || shouldChangeType(Ty,
X->getType()))) {
1312 Type *SrcTy =
X->getType();
1332 if (
Instruction *R = foldVariableSignZeroExtensionOfVariableHighBitExtract(
I))
1337 return BinaryOperator::CreateLShr(Op0, Op1);
match_combine_or< CastClass_match< OpTy, Instruction::Trunc >, OpTy > m_TruncOrSelf(const OpTy &Op)
bool isKnownNonNegative(const Value *V, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Returns true if the give value is known to be non-negative.
Value * SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, const SimplifyQuery &Q)
Given operands for a Sub, fold the result or return null.
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.
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 ...
bool hasNoUnsignedWrap() const
Determine whether the no unsigned wrap flag is set.
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.
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)
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.
BinaryOp_match< ValTy, cst_pred_ty< is_all_ones >, Instruction::Xor, true > m_Not(const ValTy &V)
Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
void setIsExact(bool b=true)
Set or clear the exact flag on this instruction, which must be an operator which supports this flag.
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.
void setIncomingValue(unsigned i, Value *V)
deferredval_ty< Value > m_Deferred(Value *const &V)
A commutative-friendly version of m_Specific().
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)
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.
FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > Tys=None)
Return the function type for an intrinsic.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", Instruction *InsertBefore=nullptr, Instruction *MDFrom=nullptr)
Instruction * foldVariableSignZeroExtensionOfVariableHighBitExtract(BinaryOperator &OldAShr)
Value * SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, const SimplifyQuery &Q)
Given operands for a Shl, fold the result or return null.
@ And
Bitwise or logical AND of integers.
static bool hasNoUnsignedWrap(BinaryOperator &I)
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.
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)
(vector float) vec_cmpeq(*A, *B) C
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static Optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
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.
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.
Value * SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact, const SimplifyQuery &Q)
Given operands for a AShr, fold the result or return nulll.
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.
static Constant * getAllOnesValue(Type *Ty)
BinaryOps getOpcode() const
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
uint64_t getZExtValue() const
Get zero extended value.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Get a value with high 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)
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.
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)
Instruction * visitShl(BinaryOperator &I)
This is an important base class in LLVM.
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.
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 Constant * get(unsigned Opcode, Constant *C1, unsigned Flags=0, Type *OnlyIfReducedTy=nullptr)
get - Return a unary operator constant expression, folding if possible.
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)
This class represents the LLVM 'select' instruction.
SimplifyQuery getWithInstruction(Instruction *I) const
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
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)
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)
Value * SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact, const SimplifyQuery &Q)
Given operands for a LShr, fold the result or return null.
static APInt getAllOnesValue(unsigned numBits)
Get the all-ones value.
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.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
bool isExact() const
Determine whether the exact flag is set.
static Value * foldShiftedShift(BinaryOperator *InnerShift, unsigned OuterShAmt, bool IsOuterShl, InstCombiner::BuilderTy &Builder)
Fold OuterShift (InnerShift X, C1), C2.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
This class represents a sign extension of integer types.
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
StringRef getName() const
Return a constant reference to the value's name.
Instruction * visitAShr(BinaryOperator &I)
static Instruction * foldShiftOfShiftedLogic(BinaryOperator &I, InstCombiner::BuilderTy &Builder)
If we have a shift-by-constant of a bitwise logic op that itself has a shift-by-constant operand with...
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Instruction * commonShiftTransforms(BinaryOperator &I)
static Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
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)
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)
bool hasNoSignedWrap() const
Determine whether the no signed wrap flag is set.
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 ...
static cl::opt< unsigned > Threshold("loop-unswitch-threshold", cl::desc("Max loop size to unswitch"), cl::init(100), cl::Hidden)
void copyIRFlags(const Value *V, bool IncludeWrapFlags=true)
Convenience method to copy supported exact, fast-math, and (optionally) wrapping flags from V to this...
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Get a value with low bits set.
void takeName(Value *V)
Transfer the name from V to this value.
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.
Value * SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, const SimplifyQuery &Q)
Given operands for an Add, fold the result or return null.
LLVM Value Representation.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
bool MaskedValueIsZero(const Value *V, const APInt &Mask, unsigned Depth=0, const Instruction *CxtI=nullptr) const
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)