15#ifndef LLVM_LIB_TRANSFORMS_INSTCOMBINE_INSTCOMBINEINTERNAL_H
16#define LLVM_LIB_TRANSFORMS_INSTCOMBINE_INSTCOMBINEINTERNAL_H
34#define DEBUG_TYPE "instcombine"
50class BlockFrequencyInfo;
55class OptimizationRemarkEmitter;
56class ProfileSummaryInfo;
57class TargetLibraryInfo;
62 public InstVisitor<InstCombinerImpl, Instruction *> {
71 :
InstCombiner(Worklist, Builder, MinimizeSize, AA, AC, TLI,
TTI, DT, ORE,
72 BFI, BPI, PSI,
DL, RPOT) {}
94 Value *OptimizePointerDifference(
119 Value *reassociateShiftAmtsOfTwoSameDirectionShifts(
121 bool AnalyzeForSignBitExtraction =
false);
122 Instruction *canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(
124 Instruction *foldVariableSignZeroExtensionOfVariableHighBitExtract(
198 const unsigned SIOpd);
201 const Twine &Suffix =
"");
206 unsigned Depth = 0)
const {
208 Val, FMF, Interested, getSimplifyQuery().getWithInstruction(CtxI),
215 unsigned Depth = 0)
const {
217 Val, Interested, getSimplifyQuery().getWithInstruction(CtxI),
Depth);
226 Constant *TruncC = ConstantExpr::getTrunc(
C, TruncTy);
229 if (ExtTruncC && ExtTruncC ==
C)
235 return getLosslessTrunc(
C, TruncTy, Instruction::ZExt);
239 return getLosslessTrunc(
C, TruncTy, Instruction::SExt);
242 std::optional<std::pair<Intrinsic::ID, SmallVector<Value *, 3>>>
247 bool isDesirableIntType(
unsigned BitWidth)
const;
248 bool shouldChangeType(
unsigned FromBitWidth,
unsigned ToBitWidth)
const;
261 bool shouldOptimizeCast(
CastInst *CI);
282 bool transformConstExprCastCall(
CallBase &Call);
305 std::optional<std::pair<Value *, Value *>> matchSymmetricPair(
Value *
LHS,
330 OverflowResult::NeverOverflows;
333 bool willNotOverflowUnsignedAdd(
const WithCache<const Value *> &
LHS,
334 const WithCache<const Value *> &
RHS,
335 const Instruction &CxtI)
const {
336 return computeOverflowForUnsignedAdd(
LHS,
RHS, &CxtI) ==
337 OverflowResult::NeverOverflows;
340 bool willNotOverflowAdd(
const Value *
LHS,
const Value *
RHS,
341 const Instruction &CxtI,
bool IsSigned)
const {
342 return IsSigned ? willNotOverflowSignedAdd(
LHS,
RHS, CxtI)
343 : willNotOverflowUnsignedAdd(
LHS,
RHS, CxtI);
346 bool willNotOverflowSignedSub(
const Value *
LHS,
const Value *
RHS,
347 const Instruction &CxtI)
const {
349 OverflowResult::NeverOverflows;
352 bool willNotOverflowUnsignedSub(
const Value *
LHS,
const Value *
RHS,
353 const Instruction &CxtI)
const {
355 OverflowResult::NeverOverflows;
358 bool willNotOverflowSub(
const Value *
LHS,
const Value *
RHS,
359 const Instruction &CxtI,
bool IsSigned)
const {
360 return IsSigned ? willNotOverflowSignedSub(
LHS,
RHS, CxtI)
361 : willNotOverflowUnsignedSub(
LHS,
RHS, CxtI);
364 bool willNotOverflowSignedMul(
const Value *
LHS,
const Value *
RHS,
365 const Instruction &CxtI)
const {
367 OverflowResult::NeverOverflows;
370 bool willNotOverflowUnsignedMul(
const Value *
LHS,
const Value *
RHS,
371 const Instruction &CxtI,
372 bool IsNSW =
false)
const {
374 OverflowResult::NeverOverflows;
377 bool willNotOverflowMul(
const Value *
LHS,
const Value *
RHS,
378 const Instruction &CxtI,
bool IsSigned)
const {
379 return IsSigned ? willNotOverflowSignedMul(
LHS,
RHS, CxtI)
380 : willNotOverflowUnsignedMul(
LHS,
RHS, CxtI);
384 const Value *
RHS,
const Instruction &CxtI,
385 bool IsSigned)
const {
387 case Instruction::Add:
return willNotOverflowAdd(
LHS,
RHS, CxtI, IsSigned);
388 case Instruction::Sub:
return willNotOverflowSub(
LHS,
RHS, CxtI, IsSigned);
389 case Instruction::Mul:
return willNotOverflowMul(
LHS,
RHS, CxtI, IsSigned);
394 Value *EmitGEPOffset(GEPOperator *
GEP,
bool RewriteGEP =
false);
397 Value *EmitGEPOffsets(ArrayRef<GEPOperator *> GEPs, GEPNoWrapFlags NW,
398 Type *IdxTy,
bool RewriteGEPs);
399 Instruction *scalarizePHI(ExtractElementInst &EI, PHINode *PN);
400 Instruction *foldBitcastExtElt(ExtractElementInst &ExtElt);
401 Instruction *foldCastedBitwiseLogic(BinaryOperator &
I);
402 Instruction *foldFBinOpOfIntCasts(BinaryOperator &
I);
404 Instruction *foldFBinOpOfIntCastsFromSign(
405 BinaryOperator &BO,
bool OpsFromSigned, std::array<Value *, 2> IntOps,
406 Constant *Op1FpC, SmallVectorImpl<WithCache<const Value *>> &OpsKnown);
407 Instruction *foldBinopOfSextBoolToSelect(BinaryOperator &
I);
408 Instruction *narrowBinOp(TruncInst &Trunc);
409 Instruction *narrowMaskedBinOp(BinaryOperator &And);
410 Instruction *narrowMathIfNoOverflow(BinaryOperator &
I);
411 Instruction *narrowFunnelShift(TruncInst &Trunc);
412 Instruction *optimizeBitCastFromPhi(CastInst &CI, PHINode *PN);
413 Instruction *matchSAddSubSat(IntrinsicInst &MinMax1);
414 Instruction *foldNot(BinaryOperator &
I);
415 Instruction *foldBinOpOfDisplacedShifts(BinaryOperator &
I);
427 Instruction::CastOps isEliminableCastPair(
const CastInst *CI1,
428 const CastInst *CI2);
429 Value *simplifyIntToPtrRoundTripCast(Value *Val);
431 Value *foldAndOrOfICmps(ICmpInst *
LHS, ICmpInst *
RHS, Instruction &
I,
432 bool IsAnd,
bool IsLogical =
false);
433 Value *foldXorOfICmps(ICmpInst *
LHS, ICmpInst *
RHS, BinaryOperator &Xor);
435 Value *foldEqOfParts(Value *Cmp0, Value *Cmp1,
bool IsAnd);
437 Value *foldAndOrOfICmpsUsingRanges(ICmpInst *ICmp1, ICmpInst *ICmp2,
443 Value *foldLogicOfFCmps(FCmpInst *
LHS, FCmpInst *
RHS,
bool IsAnd,
444 bool IsLogicalSelect =
false);
446 Instruction *foldLogicOfIsFPClass(BinaryOperator &Operator, Value *
LHS,
449 Value *foldBooleanAndOr(Value *
LHS, Value *
RHS, Instruction &
I,
bool IsAnd,
452 Value *reassociateBooleanAndOr(Value *
LHS, Value *
X, Value *
Y, Instruction &
I,
453 bool IsAnd,
bool RHSIsLogical);
457 Value *reassociateDisjointOr(Value *
LHS, Value *
RHS);
460 canonicalizeConditionalNegationViaMathToSelect(BinaryOperator &i);
462 Value *matchSelectFromAndOr(Value *
A, Value *
B, Value *
C, Value *
D,
463 bool InvertFalseVal =
false);
464 Value *getSelectCondition(Value *
A, Value *
B,
bool ABIsTheSame);
466 Instruction *foldLShrOverflowBit(BinaryOperator &
I);
467 Instruction *foldExtractOfOverflowIntrinsic(ExtractValueInst &EV);
468 Instruction *foldIntrinsicWithOverflowCommon(IntrinsicInst *
II);
469 Instruction *foldIntrinsicIsFPClass(IntrinsicInst &
II);
470 Instruction *foldFPSignBitOps(BinaryOperator &
I);
471 Instruction *foldFDivConstantDivisor(BinaryOperator &
I);
477 Instruction *foldAndOrOfSelectUsingImpliedCond(Value *Op, SelectInst &
SI,
480 Instruction *hoistFNegAboveFMulFDiv(Value *FNegOp, Instruction &FMFSource);
486 Value *simplifyNonNullOperand(Value *V,
bool HasDereferenceable,
494 auto *
SI =
new StoreInst(ConstantInt::getTrue(Ctx),
495 PoisonValue::get(PointerType::getUnqual(Ctx)),
507 assert(
I.use_empty() &&
"Cannot erase instruction that is used!");
517 Worklist.handleUseCountDecrement(
Op);
585 using InstCombiner::SimplifyDemandedBits;
589 unsigned Depth = 0)
override;
595 const APInt &DemandedMask,
602 Value *simplifyShrShlDemandedBits(
608 bool SimplifyDemandedInstructionBits(
Instruction &Inst);
612 APInt &PoisonElts,
unsigned Depth = 0,
613 bool AllowMultipleUsers =
false)
override;
639 bool AllowMultipleUses =
false);
670 bool FoldWithMultiUse =
false);
694 bool foldDeadPhiWeb(
PHINode &PN);
699 bool foldIntegerTypedPHI(
PHINode &PN);
821 bool MatchBitReversals);
829 void tryToSinkInstructionDbgVariableRecords(
833 bool removeInstructionsBeforeUnreachable(
Instruction &
I);
840 void freelyInvertAllUsersOf(
Value *V,
Value *IgnoredUser =
nullptr);
846 Value *takeLog2(
Value *
Op,
unsigned Depth,
bool AssumeNonZero,
bool DoFold);
849 if (takeLog2(
Op, 0, AssumeNonZero,
false))
850 return takeLog2(
Op, 0, AssumeNonZero,
true);
864 const bool IsTrulyNegation;
869 bool IsTrulyNegation);
872 unsigned NumValuesVisitedInThisNegator = 0;
876 using Result = std::pair<ArrayRef<Instruction *> ,
879 std::array<Value *, 2> getSortedOperandsOfBinOp(
Instruction *
I);
887 [[nodiscard]] std::optional<Result> run(
Value *Root,
bool IsNSW);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static bool foldICmpWithDominatingICmp(CmpInst *Cmp, const TargetLowering &TLI)
For pattern like:
#define LLVM_LIBRARY_VISIBILITY
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static bool isSigned(unsigned int Opcode)
static constexpr unsigned NegatorMaxNodesSSO
static constexpr unsigned NegatorDefaultMaxDepth
This file provides the interface for the instcombine pass implementation.
uint64_t IntrinsicInst * II
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
StandardInstrumentations SI(Mod->getContext(), Debug, VerifyEach)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
const SmallVectorImpl< MachineOperand > & Cond
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
static OverflowResult computeOverflowForSignedAdd(const WithCache< const Value * > &LHS, const WithCache< const Value * > &RHS, const AddOperator *Add, const SimplifyQuery &SQ)
support::ulittle16_t & Lo
support::ulittle16_t & Hi
static const uint32_t IV[8]
A private abstract base class describing the concept of an individual alias analysis implementation.
Class for arbitrary precision integers.
This class represents a conversion between pointers from one address space to another.
an instruction to allocate memory on the stack
This class represents any memset intrinsic.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
A cache of @llvm.assume calls within a function.
an instruction that atomically reads a memory location, combines it with another value,...
LLVM Basic Block Representation.
InstListType::iterator iterator
Instruction iterators...
This class represents a no-op cast from one type to another.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Conditional or Unconditional Branch instruction.
Analysis providing branch probability information.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
CallBr instruction, tracking function calls that may not return control but instead transfer it to a ...
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
This class is the base class for the comparison instructions.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
This is the shared class of boolean and integer constants.
This is an important base class in LLVM.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
This instruction compares its operands according to the predicate given to the constructor.
This class represents a cast from floating point to signed integer.
This class represents a cast from floating point to unsigned integer.
This class represents a truncation of floating point types.
Convenience struct for specifying and reasoning about fast-math flags.
An instruction for ordering other memory operations.
This class represents a freeze function that returns random concrete value if an operand is either a ...
Represents flags for the getelementptr instruction/expression.
static GEPNoWrapFlags all()
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
This instruction compares its operands according to the predicate given to the constructor.
This instruction inserts a single (scalar) element into a VectorType value.
This instruction inserts a struct field of array element value into an aggregate value.
Instruction * foldSelectToCmp(SelectInst &SI)
bool fmulByZeroIsZero(Value *MulVal, FastMathFlags FMF, const Instruction *CtxI) const
Check if fmul MulVal, +0.0 will yield +0.0 (or signed zero is ignorable).
virtual ~InstCombinerImpl()=default
KnownFPClass computeKnownFPClass(Value *Val, FastMathFlags FMF, FPClassTest Interested=fcAllFlags, const Instruction *CtxI=nullptr, unsigned Depth=0) const
Instruction * foldSelectEqualityTest(SelectInst &SI)
Instruction * foldSelectValueEquivalence(SelectInst &SI, CmpInst &CI)
InstCombinerImpl(InstructionWorklist &Worklist, BuilderTy &Builder, bool MinimizeSize, AAResults *AA, AssumptionCache &AC, TargetLibraryInfo &TLI, TargetTransformInfo &TTI, DominatorTree &DT, OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI, BranchProbabilityInfo *BPI, ProfileSummaryInfo *PSI, const DataLayout &DL, ReversePostOrderTraversal< BasicBlock * > &RPOT)
Instruction * foldVectorSelect(SelectInst &Sel)
Instruction * foldSPFofSPF(Instruction *Inner, SelectPatternFlavor SPF1, Value *A, Value *B, Instruction &Outer, SelectPatternFlavor SPF2, Value *C)
Constant * getLosslessUnsignedTrunc(Constant *C, Type *TruncTy)
bool replaceInInstruction(Value *V, Value *Old, Value *New, unsigned Depth=0)
Instruction * eraseInstFromFunction(Instruction &I) override
Combiner aware instruction erasure.
Value * tryGetLog2(Value *Op, bool AssumeNonZero)
Instruction * foldSelectInstWithICmp(SelectInst &SI, ICmpInst *ICI)
Constant * getLosslessTrunc(Constant *C, Type *TruncTy, unsigned ExtOp)
Instruction * visitInstruction(Instruction &I)
Specify what to return for unhandled instructions.
KnownFPClass computeKnownFPClass(Value *Val, FPClassTest Interested=fcAllFlags, const Instruction *CtxI=nullptr, unsigned Depth=0) const
Constant * getLosslessSignedTrunc(Constant *C, Type *TruncTy)
Value * foldSelectWithConstOpToBinOp(ICmpInst *Cmp, Value *TrueVal, Value *FalseVal)
void CreateNonTerminatorUnreachable(Instruction *InsertAt)
Create and insert the idiom we use to indicate a block is unreachable without having to rewrite the C...
Instruction * visitSelectInst(SelectInst &SI)
Instruction * foldSelectOfBools(SelectInst &SI)
Instruction * foldSelectExtConst(SelectInst &Sel)
The core instruction combiner logic.
Base class for instruction visitors.
InstructionWorklist - This is the worklist management logic for InstCombine and other simplification ...
This class represents a cast from an integer to a pointer.
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
The landingpad instruction holds all of the information necessary to generate correct exception handl...
An instruction for reading from memory.
This class represents min/max intrinsics.
static Value * Negate(bool LHSIsZero, bool IsNSW, Value *Root, InstCombinerImpl &IC)
Attempt to negate Root.
Analysis providing profile information.
This class represents a cast from a pointer to an integer.
Return a value (possibly void), from a function.
This class represents a sign extension of integer types.
This class represents the LLVM 'select' instruction.
This instruction constructs a fixed permutation of two input vectors.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Provides information about what library functions are available for the current target.
This class represents a truncation of integer types.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
This function has undefined behavior.
This represents the llvm.va_end intrinsic.
LLVM Value Representation.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
Base class of all SIMD vector types.
This class represents zero extension of integer types.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, const SimplifyQuery &SQ, unsigned Depth=0)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
LLVM_ABI void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
LLVM_ABI OverflowResult computeOverflowForUnsignedMul(const Value *LHS, const Value *RHS, const SimplifyQuery &SQ, bool IsNSW=false)
LLVM_ABI OverflowResult computeOverflowForSignedSub(const Value *LHS, const Value *RHS, const SimplifyQuery &SQ)
SelectPatternFlavor
Specific patterns of select instructions we can match.
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI OverflowResult computeOverflowForSignedMul(const Value *LHS, const Value *RHS, const SimplifyQuery &SQ)
LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
LLVM_ABI OverflowResult computeOverflowForUnsignedSub(const Value *LHS, const Value *RHS, const SimplifyQuery &SQ)
Value * Ptr
Common base pointer.
SmallVector< GEPOperator * > RHSGEPs
RHS GEPs until common base.
GEPNoWrapFlags LHSNW
LHS GEP NoWrapFlags until common base.
GEPNoWrapFlags RHSNW
RHS GEP NoWrapFlags until common base.
SmallVector< GEPOperator * > LHSGEPs
LHS GEPs until common base.
bool isExpensive() const
Whether expanding the GEP chains is expensive.
static CommonPointerBase compute(Value *LHS, Value *RHS)