diff options
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineInternal.h')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineInternal.h | 90 |
1 files changed, 73 insertions, 17 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h index 701579e1de48..bb620ad8d41c 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h +++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h @@ -16,6 +16,7 @@ #define LLVM_LIB_TRANSFORMS_INSTCOMBINE_INSTCOMBINEINTERNAL_H #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/PostOrderIterator.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/TargetFolder.h" #include "llvm/Analysis/ValueTracking.h" @@ -73,6 +74,10 @@ public: virtual ~InstCombinerImpl() = default; + /// Perform early cleanup and prepare the InstCombine worklist. + bool prepareWorklist(Function &F, + ReversePostOrderTraversal<BasicBlock *> &RPOT); + /// Run the combiner over the entire worklist until it is empty. /// /// \returns true if the IR is changed. @@ -93,6 +98,7 @@ public: Instruction *visitSub(BinaryOperator &I); Instruction *visitFSub(BinaryOperator &I); Instruction *visitMul(BinaryOperator &I); + Instruction *foldFMulReassoc(BinaryOperator &I); Instruction *visitFMul(BinaryOperator &I); Instruction *visitURem(BinaryOperator &I); Instruction *visitSRem(BinaryOperator &I); @@ -126,7 +132,6 @@ public: Instruction *FoldShiftByConstant(Value *Op0, Constant *Op1, BinaryOperator &I); Instruction *commonCastTransforms(CastInst &CI); - Instruction *commonPointerCastTransforms(CastInst &CI); Instruction *visitTrunc(TruncInst &CI); Instruction *visitZExt(ZExtInst &Zext); Instruction *visitSExt(SExtInst &Sext); @@ -193,6 +198,44 @@ public: LoadInst *combineLoadToNewType(LoadInst &LI, Type *NewTy, const Twine &Suffix = ""); + KnownFPClass computeKnownFPClass(Value *Val, FastMathFlags FMF, + FPClassTest Interested = fcAllFlags, + const Instruction *CtxI = nullptr, + unsigned Depth = 0) const { + return llvm::computeKnownFPClass(Val, FMF, DL, Interested, Depth, &TLI, &AC, + CtxI, &DT); + } + + KnownFPClass computeKnownFPClass(Value *Val, + FPClassTest Interested = fcAllFlags, + const Instruction *CtxI = nullptr, + unsigned Depth = 0) const { + return llvm::computeKnownFPClass(Val, DL, Interested, Depth, &TLI, &AC, + CtxI, &DT); + } + + /// Check if fmul \p MulVal, +0.0 will yield +0.0 (or signed zero is + /// ignorable). + bool fmulByZeroIsZero(Value *MulVal, FastMathFlags FMF, + const Instruction *CtxI) const; + + Constant *getLosslessTrunc(Constant *C, Type *TruncTy, unsigned ExtOp) { + Constant *TruncC = ConstantExpr::getTrunc(C, TruncTy); + Constant *ExtTruncC = + ConstantFoldCastOperand(ExtOp, TruncC, C->getType(), DL); + if (ExtTruncC && ExtTruncC == C) + return TruncC; + return nullptr; + } + + Constant *getLosslessUnsignedTrunc(Constant *C, Type *TruncTy) { + return getLosslessTrunc(C, TruncTy, Instruction::ZExt); + } + + Constant *getLosslessSignedTrunc(Constant *C, Type *TruncTy) { + return getLosslessTrunc(C, TruncTy, Instruction::SExt); + } + private: bool annotateAnyAllocSite(CallBase &Call, const TargetLibraryInfo *TLI); bool isDesirableIntType(unsigned BitWidth) const; @@ -252,13 +295,15 @@ private: Instruction *transformSExtICmp(ICmpInst *Cmp, SExtInst &Sext); - bool willNotOverflowSignedAdd(const Value *LHS, const Value *RHS, + bool willNotOverflowSignedAdd(const WithCache<const Value *> &LHS, + const WithCache<const Value *> &RHS, const Instruction &CxtI) const { return computeOverflowForSignedAdd(LHS, RHS, &CxtI) == OverflowResult::NeverOverflows; } - bool willNotOverflowUnsignedAdd(const Value *LHS, const Value *RHS, + bool willNotOverflowUnsignedAdd(const WithCache<const Value *> &LHS, + const WithCache<const Value *> &RHS, const Instruction &CxtI) const { return computeOverflowForUnsignedAdd(LHS, RHS, &CxtI) == OverflowResult::NeverOverflows; @@ -387,15 +432,17 @@ private: Instruction *foldAndOrOfSelectUsingImpliedCond(Value *Op, SelectInst &SI, bool IsAnd); + Instruction *hoistFNegAboveFMulFDiv(Value *FNegOp, Instruction &FMFSource); + public: /// Create and insert the idiom we use to indicate a block is unreachable /// without having to rewrite the CFG from within InstCombine. void CreateNonTerminatorUnreachable(Instruction *InsertAt) { auto &Ctx = InsertAt->getContext(); auto *SI = new StoreInst(ConstantInt::getTrue(Ctx), - PoisonValue::get(Type::getInt1PtrTy(Ctx)), + PoisonValue::get(PointerType::getUnqual(Ctx)), /*isVolatile*/ false, Align(1)); - InsertNewInstBefore(SI, *InsertAt); + InsertNewInstBefore(SI, InsertAt->getIterator()); } /// Combiner aware instruction erasure. @@ -412,6 +459,7 @@ public: // use counts. SmallVector<Value *> Ops(I.operands()); Worklist.remove(&I); + DC.removeValue(&I); I.eraseFromParent(); for (Value *Op : Ops) Worklist.handleUseCountDecrement(Op); @@ -498,6 +546,7 @@ public: /// Tries to simplify operands to an integer instruction based on its /// demanded bits. bool SimplifyDemandedInstructionBits(Instruction &Inst); + bool SimplifyDemandedInstructionBits(Instruction &Inst, KnownBits &Known); Value *SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, APInt &UndefElts, unsigned Depth = 0, @@ -535,6 +584,9 @@ public: Instruction *foldAddWithConstant(BinaryOperator &Add); + Instruction *foldSquareSumInt(BinaryOperator &I); + Instruction *foldSquareSumFP(BinaryOperator &I); + /// Try to rotate an operation below a PHI node, using PHI nodes for /// its operands. Instruction *foldPHIArgOpIntoPHI(PHINode &PN); @@ -580,6 +632,9 @@ public: Instruction *foldICmpInstWithConstantAllowUndef(ICmpInst &Cmp, const APInt &C); Instruction *foldICmpBinOp(ICmpInst &Cmp, const SimplifyQuery &SQ); + Instruction *foldICmpWithMinMaxImpl(Instruction &I, MinMaxIntrinsic *MinMax, + Value *Z, ICmpInst::Predicate Pred); + Instruction *foldICmpWithMinMax(ICmpInst &Cmp); Instruction *foldICmpEquality(ICmpInst &Cmp); Instruction *foldIRemByPowerOfTwoToBitTest(ICmpInst &I); Instruction *foldSignBitTest(ICmpInst &I); @@ -593,6 +648,8 @@ public: ConstantInt *C); Instruction *foldICmpTruncConstant(ICmpInst &Cmp, TruncInst *Trunc, const APInt &C); + Instruction *foldICmpTruncWithTruncOrExt(ICmpInst &Cmp, + const SimplifyQuery &Q); Instruction *foldICmpAndConstant(ICmpInst &Cmp, BinaryOperator *And, const APInt &C); Instruction *foldICmpXorConstant(ICmpInst &Cmp, BinaryOperator *Xor, @@ -667,8 +724,12 @@ public: bool tryToSinkInstruction(Instruction *I, BasicBlock *DestBlock); bool removeInstructionsBeforeUnreachable(Instruction &I); - bool handleUnreachableFrom(Instruction *I); - bool handlePotentiallyDeadSuccessors(BasicBlock *BB, BasicBlock *LiveSucc); + void addDeadEdge(BasicBlock *From, BasicBlock *To, + SmallVectorImpl<BasicBlock *> &Worklist); + void handleUnreachableFrom(Instruction *I, + SmallVectorImpl<BasicBlock *> &Worklist); + void handlePotentiallyDeadBlocks(SmallVectorImpl<BasicBlock *> &Worklist); + void handlePotentiallyDeadSuccessors(BasicBlock *BB, BasicBlock *LiveSucc); void freelyInvertAllUsersOf(Value *V, Value *IgnoredUser = nullptr); }; @@ -679,16 +740,11 @@ class Negator final { using BuilderTy = IRBuilder<TargetFolder, IRBuilderCallbackInserter>; BuilderTy Builder; - const DataLayout &DL; - AssumptionCache &AC; - const DominatorTree &DT; - const bool IsTrulyNegation; SmallDenseMap<Value *, Value *> NegationsCache; - Negator(LLVMContext &C, const DataLayout &DL, AssumptionCache &AC, - const DominatorTree &DT, bool IsTrulyNegation); + Negator(LLVMContext &C, const DataLayout &DL, bool IsTrulyNegation); #if LLVM_ENABLE_STATS unsigned NumValuesVisitedInThisNegator = 0; @@ -700,13 +756,13 @@ class Negator final { std::array<Value *, 2> getSortedOperandsOfBinOp(Instruction *I); - [[nodiscard]] Value *visitImpl(Value *V, unsigned Depth); + [[nodiscard]] Value *visitImpl(Value *V, bool IsNSW, unsigned Depth); - [[nodiscard]] Value *negate(Value *V, unsigned Depth); + [[nodiscard]] Value *negate(Value *V, bool IsNSW, unsigned Depth); /// Recurse depth-first and attempt to sink the negation. /// FIXME: use worklist? - [[nodiscard]] std::optional<Result> run(Value *Root); + [[nodiscard]] std::optional<Result> run(Value *Root, bool IsNSW); Negator(const Negator &) = delete; Negator(Negator &&) = delete; @@ -716,7 +772,7 @@ class Negator final { public: /// Attempt to negate \p Root. Retuns nullptr if negation can't be performed, /// otherwise returns negated value. - [[nodiscard]] static Value *Negate(bool LHSIsZero, Value *Root, + [[nodiscard]] static Value *Negate(bool LHSIsZero, bool IsNSW, Value *Root, InstCombinerImpl &IC); }; |
