20 using namespace PatternMatch;
22 #define DEBUG_TYPE "instcombine"
29 if (SimplifyDemandedInstructionBits(I))
33 if (isa<Constant>(Op0))
38 if (
Constant *CUI = dyn_cast<Constant>(Op1))
39 if (
Instruction *Res = FoldShiftByConstant(Op0, CUI, I))
92 uint32_t OrigBitWidth = OrigTy->getScalarSizeInBits();
93 uint32_t BitWidth = Ty->getScalarSizeInBits();
109 default:
return false;
117 case Instruction::Shl: {
120 if (!CI)
return false;
123 if (isLeftShift)
return true;
126 if (CI->
getValue() == NumBits)
return true;
142 case Instruction::LShr: {
145 if (!CI)
return false;
148 if (!isLeftShift)
return true;
151 if (CI->
getValue() == NumBits)
return true;
192 if (
Constant *C = dyn_cast<Constant>(V)) {
218 case Instruction::Shl: {
229 if (NewShAmt >= TypeWidth)
260 case Instruction::LShr: {
270 if (NewShAmt >= TypeWidth)
313 isLeftShift, IC, DL));
323 bool isLeftShift = I.
getOpcode() == Instruction::Shl;
327 COp1 = dyn_cast_or_null<ConstantInt>(CV->getSplatValue());
329 COp1 = dyn_cast_or_null<ConstantInt>(CV->getSplatValue());
338 if (I.
getOpcode() != Instruction::AShr &&
340 DEBUG(
dbgs() <<
"ICE: GetShiftedValue propagating shift through expression"
341 " to eliminate shift:\n IN: " << *Op0 <<
"\n SH: " << I <<
"\n");
343 return ReplaceInstUsesWith(
351 assert(!COp1->
uge(TypeBits) &&
352 "Shift over the type width should have been removed already");
356 if (BO->getOpcode() == Instruction::Mul && isLeftShift)
357 if (
Constant *BOOp = dyn_cast<Constant>(BO->getOperand(1)))
365 if (isa<PHINode>(Op0))
370 if (
TruncInst *TI = dyn_cast<TruncInst>(Op0)) {
389 unsigned DstSize = TI->getType()->getScalarSizeInBits();
399 assert(I.
getOpcode() == Instruction::LShr &&
"Unknown logical shift");
404 Value *
And = Builder->CreateAnd(NSh,
418 switch (Op0BO->getOpcode()) {
420 case Instruction::Add:
426 if (isLeftShift && Op0BO->getOperand(1)->hasOneUse() &&
430 Builder->CreateShl(Op0BO->getOperand(0), Op1, Op0BO->
getName());
432 Value *
X = Builder->CreateBinOp(Op0BO->getOpcode(), YS, V1,
433 Op0BO->getOperand(1)->
getName());
440 return BinaryOperator::CreateAnd(X, Mask);
444 Value *Op0BOOp1 = Op0BO->getOperand(1);
445 if (isLeftShift && Op0BOOp1->
hasOneUse() &&
450 Builder->CreateShl(Op0BO->getOperand(0), Op1,
460 case Instruction::Sub: {
462 if (isLeftShift && Op0BO->getOperand(0)->hasOneUse() &&
466 Builder->CreateShl(Op0BO->getOperand(1), Op1, Op0BO->
getName());
468 Value *
X = Builder->CreateBinOp(Op0BO->getOpcode(), V1, YS,
469 Op0BO->getOperand(0)->
getName());
476 return BinaryOperator::CreateAnd(X, Mask);
480 if (isLeftShift && Op0BO->getOperand(0)->hasOneUse() &&
481 match(Op0BO->getOperand(0),
485 Builder->CreateShl(Op0BO->getOperand(1), Op1, Op0BO->
getName());
500 if (
ConstantInt *Op0C = dyn_cast<ConstantInt>(Op0BO->getOperand(1))) {
502 bool highBitSet =
false;
504 switch (Op0BO->getOpcode()) {
505 default: isValid =
false;
break;
506 case Instruction::Add:
507 isValid = isLeftShift;
524 if (isValid && I.
getOpcode() == Instruction::AShr)
525 isValid = Op0C->getValue()[TypeBits-1] == highBitSet;
531 Builder->CreateBinOp(I.
getOpcode(), Op0BO->getOperand(0), Op1);
543 if (ShiftOp && !ShiftOp->
isShift())
546 if (ShiftOp && isa<ConstantInt>(ShiftOp->
getOperand(1))) {
563 assert(ShiftAmt2 != 0 &&
"Should have been simplified earlier");
564 if (ShiftAmt1 == 0)
return nullptr;
571 uint32_t AmtSum = ShiftAmt1+ShiftAmt2;
574 if (AmtSum >= TypeBits) {
584 if (ShiftAmt1 == ShiftAmt2) {
586 if (I.
getOpcode() == Instruction::LShr &&
587 ShiftOp->
getOpcode() == Instruction::Shl) {
589 return BinaryOperator::CreateAnd(X,
592 }
else if (ShiftAmt1 < ShiftAmt2) {
593 uint32_t ShiftDiff = ShiftAmt2-ShiftAmt1;
599 ShiftOp->
getOpcode() != Instruction::Shl &&
601 assert(ShiftOp->
getOpcode() == Instruction::LShr ||
602 ShiftOp->
getOpcode() == Instruction::AShr);
612 if (I.
getOpcode() == Instruction::LShr &&
613 ShiftOp->
getOpcode() == Instruction::Shl) {
622 Value *Shift = Builder->CreateLShr(X, ShiftDiffCst);
625 return BinaryOperator::CreateAnd(Shift,
631 if (I.
getOpcode() == Instruction::AShr &&
632 ShiftOp->
getOpcode() == Instruction::Shl) {
643 assert(ShiftAmt2 < ShiftAmt1);
644 uint32_t ShiftDiff = ShiftAmt1-ShiftAmt2;
650 ShiftOp->
getOpcode() != Instruction::Shl &&
660 if (I.
getOpcode() == Instruction::LShr &&
661 ShiftOp->
getOpcode() == Instruction::Shl) {
670 Value *Shift = Builder->CreateShl(X, ShiftDiffCst);
673 return BinaryOperator::CreateAnd(Shift,
679 if (I.
getOpcode() == Instruction::AShr &&
680 ShiftOp->
getOpcode() == Instruction::Shl) {
696 if (
Value *V = SimplifyVectorOp(I))
697 return ReplaceInstUsesWith(I, V);
702 return ReplaceInstUsesWith(I, V);
708 unsigned ShAmt = Op1C->getZExtValue();
738 if (
Value *V = SimplifyVectorOp(I))
739 return ReplaceInstUsesWith(I, V);
743 return ReplaceInstUsesWith(I, V);
750 if (
ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
751 unsigned ShAmt = Op1C->getZExtValue();
758 if ((II->getIntrinsicID() == Intrinsic::ctlz ||
759 II->getIntrinsicID() == Intrinsic::cttz ||
760 II->getIntrinsicID() == Intrinsic::ctpop) &&
762 bool isCtPop = II->getIntrinsicID() == Intrinsic::ctpop;
764 Value *Cmp = Builder->CreateICmpEQ(II->getArgOperand(0), RHS);
765 return new ZExtInst(Cmp, II->getType());
782 if (
Value *V = SimplifyVectorOp(I))
783 return ReplaceInstUsesWith(I, V);
787 return ReplaceInstUsesWith(I, V);
794 if (
ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
795 unsigned ShAmt = Op1C->getZExtValue();
806 if (
ZExtInst *ZI = dyn_cast<ZExtInst>(X)) {
807 uint32_t SrcBits = ZI->getOperand(0)->getType()->getScalarSizeInBits();
808 uint32_t DestBits = ZI->getType()->getScalarSizeInBits();
809 if (Op1C->getZExtValue() == DestBits-SrcBits)
810 return new SExtInst(ZI->getOperand(0), ZI->getType());
827 return BinaryOperator::CreateLShr(Op0, Op1);
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
ConstantDataVector - A vector constant whose element type is a simple 1/2/4/8-byte integer or float/d...
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
A parsed version of the target data layout string in and methods for querying it. ...
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag...
static APInt getSignBit(unsigned BitWidth)
Get the SignBit for a specific bit width.
BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)
This class represents zero extension of integer types.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Get a value with low bits set.
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
void Add(Instruction *I)
Add - Add the specified instruction to the worklist if it isn't already in it.
This class represents a sign extension of integer types.
Constant * ConstantFoldConstantExpression(const ConstantExpr *CE, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstantExpression - Attempt to fold the constant expression using the specified DataLayo...
static Constant * getNullValue(Type *Ty)
StringRef getName() const
Return a constant reference to the value's name.
bool uge(uint64_t Num) const
This function will return true iff this constant represents a value with active bits bigger than 64 b...
bool match(Val *V, const Pattern &P)
SelectInst - This class represents the LLVM 'select' instruction.
Instruction * commonShiftTransforms(BinaryOperator &I)
const APInt & getValue() const
Return the constant as an APInt value reference.
BinOp2_match< LHS, RHS, Instruction::LShr, Instruction::AShr > m_Shr(const LHS &L, const RHS &R)
Matches LShr or AShr.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void setHasNoUnsignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag...
APInt LLVM_ATTRIBUTE_UNUSED_RESULT lshr(unsigned shiftAmt) const
Logical right-shift function.
The core instruction combiner logic.
bool MaskedValueIsZero(Value *V, const APInt &Mask, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr)
MaskedValueIsZero - Return true if 'V & Mask' is known to be zero.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
static Constant * get(unsigned Opcode, Constant *C1, Constant *C2, unsigned Flags=0, Type *OnlyIfReducedTy=nullptr)
get - Return a binary or shift operator constant expression, folding if possible. ...
static Constant * getZExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
ConstantExpr - a constant value that is initialized with an expression using other constant values...
uint64_t getLimitedValue(uint64_t Limit=~0ULL) const
getLimitedValue - If the value is smaller than the specified limit, return it, otherwise return the l...
bool isLogicalShift() const
isLogicalShift - Return true if this is a logical shift left or a logical shift right.
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power of 2.
void takeName(Value *V)
Transfer the name from V to this value.
This class represents a truncation of integer types.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
unsigned getNumIncomingValues() const
getNumIncomingValues - Return the number of incoming edges
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Get a value with high bits set.
OneUse_match< T > m_OneUse(const T &SubPattern)
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
static bool CanEvaluateTruncated(Value *V, Type *Ty, InstCombiner &IC, Instruction *CxtI)
CanEvaluateTruncated - Return true if we can evaluate the specified expression tree as type Ty instea...
This is an important base class in LLVM.
APInt Or(const APInt &LHS, const APInt &RHS)
Bitwise OR function for APInt.
APInt Xor(const APInt &LHS, const APInt &RHS)
Bitwise XOR function for APInt.
Value * SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr)
SimplifyShlInst - Given operands for a Shl, see if we can fold the result.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
Value * getOperand(unsigned i) const
Class to represent integer types.
ConstantVector - Constant Vector Declarations.
Instruction * visitLShr(BinaryOperator &I)
LLVMContext & getContext() const
All values hold a context through their type.
bool hasNoSignedWrap() const
Determine whether the no signed wrap flag is set.
const Value * getTrueValue() const
void setIsExact(bool b=true)
Set or clear the exact flag on this instruction, which must be an operator which supports this flag...
InstCombineWorklist & Worklist
A worklist of the instructions that need to be simplified.
BinaryOps getOpcode() const
static Constant * getSplat(unsigned NumElts, Constant *Elt)
getSplat - Return a ConstantVector with the specified constant in each element.
This is the shared class of boolean and integer constants.
Value * getIncomingValue(unsigned i) const
getIncomingValue - Return incoming value number x
unsigned getScalarSizeInBits() const LLVM_READONLY
getScalarSizeInBits - If this is a vector type, return the getPrimitiveSizeInBits value for the eleme...
Type * getType() const
All values are typed, get the type of this value.
unsigned ComputeNumSignBits(Value *Op, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr)
ComputeNumSignBits - Return the number of times the sign bit of the register is replicated into the o...
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.
bool isExact() const
Determine whether the exact flag is set.
void setOperand(unsigned i, Value *Val)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned Log2_32(uint32_t Value)
Log2_32 - This function returns the floor log base 2 of the specified value, -1 if the value is zero...
VectorType - Class to represent vector types.
Class for arbitrary precision integers.
TargetLibraryInfo * getTargetLibraryInfo() const
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.
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
APInt And(const APInt &LHS, const APInt &RHS)
Bitwise AND function for APInt.
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
static Value * GetShiftedValue(Value *V, unsigned NumBits, bool isLeftShift, InstCombiner &IC, const DataLayout &DL)
GetShiftedValue - When CanEvaluateShifted returned true for an expression, this value inserts the new...
bool hasOneUse() const
Return true if there is exactly one user of this value.
static Constant * getShl(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
Value * SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr)
SimplifyLShrInst - Given operands for a LShr, see if we can fold the result.
LLVM Value Representation.
Value * SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr)
SimplifyAShrInst - Given operands for a AShr, see if we can fold the result.
bool hasNoUnsignedWrap() const
Determine whether the no unsigned wrap flag is set.
This file provides internal interfaces used to implement the InstCombine.
unsigned getOpcode() const
getOpcode() returns a member of one of the enums like Instruction::Add.
bool isPowerOf2_32(uint32_t Value)
isPowerOf2_32 - This function returns true if the argument is a power of two > 0. ...
const Value * getFalseValue() const
Instruction * visitAShr(BinaryOperator &I)
void setIncomingValue(unsigned i, Value *V)
Instruction * visitShl(BinaryOperator &I)
static bool CanEvaluateShifted(Value *V, unsigned NumBits, bool isLeftShift, InstCombiner &IC, Instruction *CxtI)
CanEvaluateShifted - See if we can compute the specified value, but shifted logically to the left or ...
static BinaryOperator * CreateMul(Value *S1, Value *S2, const Twine &Name, Instruction *InsertBefore, Value *FlagsOp)
op_range incoming_values()
Instruction * FoldShiftByConstant(Value *Op0, Constant *Op1, BinaryOperator &I)
IntrinsicInst - A useful wrapper class for inspecting calls to intrinsic functions.