23 using namespace llvm::PatternMatch;
25 #define DEBUG_TYPE "instcombine"
32 const DILocation *Loc = FirstInst->getDebugLoc();
46 assert(isa<BinaryOperator>(FirstInst) || isa<CmpInst>(FirstInst));
65 if (
CmpInst *CI = dyn_cast<CmpInst>(I))
66 if (CI->getPredicate() != cast<CmpInst>(FirstInst)->getPredicate())
70 if (I->
getOperand(0) != LHSVal) LHSVal =
nullptr;
71 if (I->
getOperand(1) != RHSVal) RHSVal =
nullptr;
78 if (!LHSVal && !RHSVal)
85 PHINode *NewLHS =
nullptr, *NewRHS =
nullptr;
90 InsertNewInstBefore(NewLHS, PN);
98 InsertNewInstBefore(NewRHS, PN);
103 if (NewLHS || NewRHS) {
117 if (
CmpInst *CIOp = dyn_cast<CmpInst>(FirstInst)) {
133 NewBinOp->setDebugLoc(PHIArgMergedDebugLoc(PN));
144 bool AllBasePointersAreAllocas =
true;
149 bool NeededPhi =
false;
151 bool AllInBounds =
true;
163 if (AllBasePointersAreAllocas &&
166 AllBasePointersAreAllocas =
false;
192 FixedOperands[
op] =
nullptr;
203 if (AllBasePointersAreAllocas)
210 bool HasAnyPHIs =
false;
211 for (
unsigned i = 0, e = FixedOperands.size();
i != e; ++
i) {
212 if (FixedOperands[
i])
continue;
216 InsertNewInstBefore(NewPN, PN);
219 OperandPhis[
i] = NewPN;
220 FixedOperands[
i] = NewPN;
231 for (
unsigned op = 0, e = OperandPhis.size();
op != e; ++
op)
233 OpPhi->addIncoming(InGEP->
getOperand(op), InBB);
237 Value *Base = FixedOperands[0];
257 for (++BBI; BBI !=
E; ++BBI)
258 if (BBI->mayWriteToMemory())
264 bool isAddressTaken =
false;
266 if (isa<LoadInst>(U))
continue;
269 if (
SI->getOperand(1) == AI)
continue;
271 isAddressTaken =
true;
275 if (!isAddressTaken && AI->isStaticAlloca())
361 unsigned KnownIDs[] = {
373 for (
unsigned ID : KnownIDs)
381 if (NewInVal != InVal)
392 InsertNewInstBefore(NewPN, PN);
400 cast<LoadInst>(IncValue)->setVolatile(
false);
420 if (NumIncomingValues < 3)
424 Type *NarrowType =
nullptr;
426 if (
auto *Zext = dyn_cast<ZExtInst>(V)) {
427 NarrowType = Zext->getSrcTy();
437 unsigned NumZexts = 0;
438 unsigned NumConsts = 0;
440 if (
auto *Zext = dyn_cast<ZExtInst>(V)) {
442 if (Zext->getSrcTy() != NarrowType || !Zext->hasOneUse())
444 NewIncoming.
push_back(Zext->getOperand(0));
446 }
else if (
auto *
C = dyn_cast<Constant>(V)) {
465 if (NumConsts == 0 || NumZexts < 2)
473 for (
unsigned i = 0; i != NumIncomingValues; ++
i)
476 InsertNewInstBefore(NewPhi, Phi);
492 if (isa<GetElementPtrInst>(FirstInst))
493 return FoldPHIArgGEPIntoPHI(PN);
494 if (isa<LoadInst>(FirstInst))
495 return FoldPHIArgLoadIntoPHI(PN);
502 Type *CastSrcTy =
nullptr;
504 if (isa<CastInst>(FirstInst)) {
510 if (!ShouldChangeType(PN.
getType(), CastSrcTy))
513 }
else if (isa<BinaryOperator>(FirstInst) || isa<CmpInst>(FirstInst)) {
518 return FoldPHIArgBinOpIntoPHI(PN);
548 if (NewInVal != InVal)
560 InsertNewInstBefore(NewPN, PN);
565 if (
CastInst *FirstCI = dyn_cast<CastInst>(FirstInst)) {
572 if (
BinaryOperator *BinOp = dyn_cast<BinaryOperator>(FirstInst)) {
583 CmpInst *CIOp = cast<CmpInst>(FirstInst);
597 if (!PotentiallyDeadPHIs.
insert(PN).second)
601 if (PotentiallyDeadPHIs.
size() == 16)
616 if (!ValueEqualPHIs.
insert(PN).second)
620 if (ValueEqualPHIs.
size() == 16)
626 if (
PHINode *OpPN = dyn_cast<PHINode>(
Op)) {
629 }
else if (
Op != NonPhiInVal)
639 assert(isa<IntegerType>(PN.
getType()) &&
"Expect only intger type phi");
641 if (
auto *ConstVA = dyn_cast<ConstantInt>(V))
642 if (!ConstVA->isZeroValue())
648 struct PHIUsageRecord {
654 : PHIId(pn), Shift(Sh), Inst(User) {}
656 bool operator<(
const PHIUsageRecord &RHS)
const {
657 if (PHIId < RHS.PHIId)
return true;
658 if (PHIId > RHS.PHIId)
return false;
659 if (Shift < RHS.Shift)
return true;
660 if (Shift > RHS.Shift)
return false;
661 return Inst->getType()->getPrimitiveSizeInBits() <
662 RHS.Inst->getType()->getPrimitiveSizeInBits();
666 struct LoweredPHIRecord {
671 LoweredPHIRecord(
PHINode *pn,
unsigned Sh,
Type *Ty)
672 : PN(pn), Shift(Sh), Width(Ty->getPrimitiveSizeInBits()) {}
675 LoweredPHIRecord(
PHINode *pn,
unsigned Sh)
676 : PN(pn), Shift(Sh), Width(0) {}
684 return LoweredPHIRecord(
nullptr, 0);
687 return LoweredPHIRecord(
nullptr, 1);
693 static bool isEqual(
const LoweredPHIRecord &LHS,
694 const LoweredPHIRecord &RHS) {
695 return LHS.PN == RHS.PN && LHS.Shift == RHS.Shift &&
696 LHS.Width == RHS.Width;
723 PHIsInspected.
insert(&FirstPhi);
725 for (
unsigned PHIId = 0; PHIId != PHIsToSlice.
size(); ++PHIId) {
726 PHINode *PN = PHIsToSlice[PHIId];
748 if (
PHINode *UserPN = dyn_cast<PHINode>(UserI)) {
749 if (PHIsInspected.
insert(UserPN).second)
755 if (isa<TruncInst>(UserI)) {
756 PHIUsers.
push_back(PHIUsageRecord(PHIId, 0, UserI));
761 if (UserI->
getOpcode() != Instruction::LShr ||
766 unsigned Shift = cast<ConstantInt>(UserI->
getOperand(1))->getZExtValue();
772 if (PHIUsers.
empty())
779 DEBUG(
dbgs() <<
"SLICING UP PHI: " << FirstPhi <<
'\n';
780 for (
unsigned i = 1, e = PHIsToSlice.
size(); i != e; ++
i)
781 dbgs() <<
"AND USER PHI #" << i <<
": " << *PHIsToSlice[
i] <<
'\n';
792 for (
unsigned UserI = 0, UserE = PHIUsers.
size(); UserI != UserE; ++UserI) {
793 unsigned PHIId = PHIUsers[UserI].PHIId;
794 PHINode *PN = PHIsToSlice[PHIId];
795 unsigned Offset = PHIUsers[UserI].Shift;
796 Type *Ty = PHIUsers[UserI].Inst->getType();
802 if ((EltPHI = ExtractedVals[LoweredPHIRecord(PN, Offset, Ty)]) ==
nullptr) {
808 "Truncate didn't shrink phi?");
812 Value *&PredVal = PredValues[Pred];
828 if (
PHINode *InPHI = dyn_cast<PHINode>(PN)) {
831 if (
Value *Res = ExtractedVals[LoweredPHIRecord(InPHI, Offset, Ty)]) {
844 Res = Builder->CreateTrunc(Res, Ty,
"extract.t");
853 if (PHIsInspected.
count(OldInVal)) {
855 find(PHIsToSlice, OldInVal) - PHIsToSlice.begin();
856 PHIUsers.
push_back(PHIUsageRecord(RefPHIId, Offset,
857 cast<Instruction>(Res)));
863 DEBUG(
dbgs() <<
" Made element PHI for offset " << Offset <<
": "
865 ExtractedVals[LoweredPHIRecord(PN, Offset, Ty)] = EltPHI;
869 replaceInstUsesWith(*PHIUsers[UserI].Inst, EltPHI);
875 for (
unsigned i = 1, e = PHIsToSlice.size(); i != e; ++
i)
876 replaceInstUsesWith(*PHIsToSlice[i], Undef);
877 return replaceInstUsesWith(FirstPhi, Undef);
884 return replaceInstUsesWith(PN, V);
886 if (
Instruction *Result = FoldPHIArgZextsIntoPHI(PN))
906 if (
PHINode *PU = dyn_cast<PHINode>(PHIUser)) {
908 PotentiallyDeadPHIs.
insert(&PN);
920 (isa<BinaryOperator>(PHIUser) || isa<GetElementPtrInst>(PHIUser)) &&
958 while (InValNo != NumIncomingVals &&
962 if (InValNo != NumIncomingVals) {
967 for (++InValNo; InValNo != NumIncomingVals; ++InValNo) {
969 if (OpVal != NonPhiInVal && !isa<PHINode>(OpVal))
976 if (InValNo == NumIncomingVals) {
979 return replaceInstUsesWith(PN, NonPhiInVal);
1014 if (
Instruction *Res = SliceUpIllegalIntegerPHI(PN))
void push_back(const T &Elt)
This class is the base class for the comparison instructions.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
Type * getSourceElementType() const
match_zero m_Zero()
Match an arbitrary zero/null constant.
unsigned getNumOperands() const
static LoweredPHIRecord getEmptyKey()
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
An instruction for reading from memory.
bool isEquality() const
This is just a convenience that dispatches to the subclasses.
static ConstantInt * GetAnyNonZeroConstInt(PHINode &PN)
Return an existing non-zero constant if this phi node has one, otherwise return constant 1...
static bool isSafeAndProfitableToSinkLoad(LoadInst *L)
Return true if we know that it is safe to sink the load out of the block that defines it...
StringRef getName() const
Return a constant reference to the value's name.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
iterator begin()
Instruction iterator methods.
void copyIRFlags(const Value *V)
Convenience method to copy supported wrapping, exact, and fast-math flags from V to this instruction...
bool match(Val *V, const Pattern &P)
static bool PHIsEqualValue(PHINode *PN, Value *NonPhiInVal, SmallPtrSetImpl< PHINode * > &ValueEqualPHIs)
Return true if this phi node is always equal to NonPhiInVal.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
This is the base class for all instructions that perform data casts.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
void setIsInBounds(bool b=true)
Set or clear the inbounds flag on this GEP instruction.
Instruction * SliceUpIllegalIntegerPHI(PHINode &PN)
This is an integer PHI and we know that it has an illegal type: see if it is only used by trunc or tr...
static const DILocation * getMergedLocation(const DILocation *LocA, const DILocation *LocB)
When two instructions are combined into a single instruction we also need to combine the original loc...
static bool isEqual(const LoweredPHIRecord &LHS, const LoweredPHIRecord &RHS)
static bool DeadPHICycle(PHINode *PN, SmallPtrSetImpl< PHINode * > &PotentiallyDeadPHIs)
Return true if this PHI node is only used by a PHI node cycle that is dead.
LLVM_NODISCARD bool empty() const
static Constant * getZExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction...
static CmpInst * Create(OtherOps Op, Predicate predicate, Value *S1, Value *S2, const Twine &Name="", Instruction *InsertBefore=nullptr)
Construct a compare instruction, given the opcode, the predicate and the two operands.
An instruction for storing to memory.
bool isAtomic() const
Return true if this instruction has an AtomicOrdering of unordered or higher.
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
bool isInBounds() const
Determine whether the GEP has the inbounds flag.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
unsigned getNumIncomingValues() const
Return the number of incoming edges.
unsigned getNumSuccessors() const
Return the number of successors that this terminator has.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
Subclasses of this class are all able to terminate a basic block.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important base class in LLVM.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
This instruction compares its operands according to the predicate given to the constructor.
Value * getOperand(unsigned i) const
self_iterator getIterator()
Predicate getPredicate() const
Return the predicate for this instruction.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
bool hasAllConstantIndices() const
Return true if all of the indices of this GEP are constant integers.
static CastInst * CreateZExtOrBitCast(Value *S, Type *Ty, const Twine &Name="", Instruction *InsertBefore=nullptr)
Create a ZExt or BitCast cast instruction.
Instruction * visitPHINode(PHINode &PN)
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
BinaryOps getOpcode() const
Iterator for intrusive lists based on ilist_node.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is the shared class of boolean and integer constants.
auto find(R &&Range, const T &Val) -> decltype(std::begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
void setIncomingBlock(unsigned i, BasicBlock *BB)
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Type * getType() const
All values are typed, get the type of this value.
Instruction * user_back()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
bool isVolatile() const
Return true if this is a load from a volatile memory location.
static LoweredPHIRecord getTombstoneKey()
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 PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
void setOperand(unsigned i, Value *Val)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isIntegerTy() const
True if this is an instance of IntegerType.
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.
iterator_range< user_iterator > users()
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 ...
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
unsigned getAlignment() const
Return the alignment of the access that is being performed.
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
bool hasOneUse() const
Return true if there is exactly one user of this value.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
OtherOps getOpcode() const
Get the opcode casted to the right type.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool operator<(int64_t V1, const APSInt &V2)
unsigned getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM Value Representation.
This file provides internal interfaces used to implement the InstCombine.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
static unsigned getHashValue(const LoweredPHIRecord &Val)
bool isKnownNonZero(const Value *V, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr)
Return true if the given value is known to be non-zero when defined.
Value * SimplifyInstruction(Instruction *I, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr)
See if we can compute a simplified version of this instruction.
bool isSameOperationAs(const Instruction *I, unsigned flags=0) const
This function determines if the specified instruction executes the same operation as the current one...
static bool isVolatile(Instruction *Inst)
void setIncomingValue(unsigned i, Value *V)
op_range incoming_values()
int getBasicBlockIndex(const BasicBlock *BB) const
Return the first index of the specified basic block in the value list for this PHI.
void combineMetadata(Instruction *K, const Instruction *J, ArrayRef< unsigned > KnownIDs)
Combine the metadata of two instructions so that K can replace J.
const BasicBlock * getParent() const
an instruction to allocate memory on the stack