Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
35266 views
//===- InstCombineInternal.h - InstCombine pass internals -------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8/// \file9///10/// This file provides internal interfaces used to implement the InstCombine.11//12//===----------------------------------------------------------------------===//1314#ifndef LLVM_LIB_TRANSFORMS_INSTCOMBINE_INSTCOMBINEINTERNAL_H15#define LLVM_LIB_TRANSFORMS_INSTCOMBINE_INSTCOMBINEINTERNAL_H1617#include "llvm/ADT/Statistic.h"18#include "llvm/ADT/PostOrderIterator.h"19#include "llvm/Analysis/InstructionSimplify.h"20#include "llvm/Analysis/TargetFolder.h"21#include "llvm/Analysis/ValueTracking.h"22#include "llvm/IR/IRBuilder.h"23#include "llvm/IR/InstVisitor.h"24#include "llvm/IR/PatternMatch.h"25#include "llvm/IR/Value.h"26#include "llvm/Support/Debug.h"27#include "llvm/Support/KnownBits.h"28#include "llvm/Transforms/InstCombine/InstCombiner.h"29#include "llvm/Transforms/Utils/Local.h"30#include <cassert>3132#define DEBUG_TYPE "instcombine"33#include "llvm/Transforms/Utils/InstructionWorklist.h"3435using namespace llvm::PatternMatch;3637// As a default, let's assume that we want to be aggressive,38// and attempt to traverse with no limits in attempt to sink negation.39static constexpr unsigned NegatorDefaultMaxDepth = ~0U;4041// Let's guesstimate that most often we will end up visiting/producing42// fairly small number of new instructions.43static constexpr unsigned NegatorMaxNodesSSO = 16;4445namespace llvm {4647class AAResults;48class APInt;49class AssumptionCache;50class BlockFrequencyInfo;51class DataLayout;52class DominatorTree;53class GEPOperator;54class GlobalVariable;55class LoopInfo;56class OptimizationRemarkEmitter;57class ProfileSummaryInfo;58class TargetLibraryInfo;59class User;6061class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final62: public InstCombiner,63public InstVisitor<InstCombinerImpl, Instruction *> {64public:65InstCombinerImpl(InstructionWorklist &Worklist, BuilderTy &Builder,66bool MinimizeSize, AAResults *AA, AssumptionCache &AC,67TargetLibraryInfo &TLI, TargetTransformInfo &TTI,68DominatorTree &DT, OptimizationRemarkEmitter &ORE,69BlockFrequencyInfo *BFI, BranchProbabilityInfo *BPI,70ProfileSummaryInfo *PSI, const DataLayout &DL, LoopInfo *LI)71: InstCombiner(Worklist, Builder, MinimizeSize, AA, AC, TLI, TTI, DT, ORE,72BFI, BPI, PSI, DL, LI) {}7374virtual ~InstCombinerImpl() = default;7576/// Perform early cleanup and prepare the InstCombine worklist.77bool prepareWorklist(Function &F,78ReversePostOrderTraversal<BasicBlock *> &RPOT);7980/// Run the combiner over the entire worklist until it is empty.81///82/// \returns true if the IR is changed.83bool run();8485// Visitation implementation - Implement instruction combining for different86// instruction types. The semantics are as follows:87// Return Value:88// null - No change was made89// I - Change was made, I is still valid, I may be dead though90// otherwise - Change was made, replace I with returned instruction91//92Instruction *visitFNeg(UnaryOperator &I);93Instruction *visitAdd(BinaryOperator &I);94Instruction *visitFAdd(BinaryOperator &I);95Value *OptimizePointerDifference(96Value *LHS, Value *RHS, Type *Ty, bool isNUW);97Instruction *visitSub(BinaryOperator &I);98Instruction *visitFSub(BinaryOperator &I);99Instruction *visitMul(BinaryOperator &I);100Instruction *foldPowiReassoc(BinaryOperator &I);101Instruction *foldFMulReassoc(BinaryOperator &I);102Instruction *visitFMul(BinaryOperator &I);103Instruction *visitURem(BinaryOperator &I);104Instruction *visitSRem(BinaryOperator &I);105Instruction *visitFRem(BinaryOperator &I);106bool simplifyDivRemOfSelectWithZeroOp(BinaryOperator &I);107Instruction *commonIRemTransforms(BinaryOperator &I);108Instruction *commonIDivTransforms(BinaryOperator &I);109Instruction *visitUDiv(BinaryOperator &I);110Instruction *visitSDiv(BinaryOperator &I);111Instruction *visitFDiv(BinaryOperator &I);112Value *simplifyRangeCheck(ICmpInst *Cmp0, ICmpInst *Cmp1, bool Inverted);113Instruction *visitAnd(BinaryOperator &I);114Instruction *visitOr(BinaryOperator &I);115bool sinkNotIntoLogicalOp(Instruction &I);116bool sinkNotIntoOtherHandOfLogicalOp(Instruction &I);117Instruction *visitXor(BinaryOperator &I);118Instruction *visitShl(BinaryOperator &I);119Value *reassociateShiftAmtsOfTwoSameDirectionShifts(120BinaryOperator *Sh0, const SimplifyQuery &SQ,121bool AnalyzeForSignBitExtraction = false);122Instruction *canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(123BinaryOperator &I);124Instruction *foldVariableSignZeroExtensionOfVariableHighBitExtract(125BinaryOperator &OldAShr);126Instruction *visitAShr(BinaryOperator &I);127Instruction *visitLShr(BinaryOperator &I);128Instruction *commonShiftTransforms(BinaryOperator &I);129Instruction *visitFCmpInst(FCmpInst &I);130CmpInst *canonicalizeICmpPredicate(CmpInst &I);131Instruction *visitICmpInst(ICmpInst &I);132Instruction *FoldShiftByConstant(Value *Op0, Constant *Op1,133BinaryOperator &I);134Instruction *commonCastTransforms(CastInst &CI);135Instruction *visitTrunc(TruncInst &CI);136Instruction *visitZExt(ZExtInst &Zext);137Instruction *visitSExt(SExtInst &Sext);138Instruction *visitFPTrunc(FPTruncInst &CI);139Instruction *visitFPExt(CastInst &CI);140Instruction *visitFPToUI(FPToUIInst &FI);141Instruction *visitFPToSI(FPToSIInst &FI);142Instruction *visitUIToFP(CastInst &CI);143Instruction *visitSIToFP(CastInst &CI);144Instruction *visitPtrToInt(PtrToIntInst &CI);145Instruction *visitIntToPtr(IntToPtrInst &CI);146Instruction *visitBitCast(BitCastInst &CI);147Instruction *visitAddrSpaceCast(AddrSpaceCastInst &CI);148Instruction *foldItoFPtoI(CastInst &FI);149Instruction *visitSelectInst(SelectInst &SI);150Instruction *visitCallInst(CallInst &CI);151Instruction *visitInvokeInst(InvokeInst &II);152Instruction *visitCallBrInst(CallBrInst &CBI);153154Instruction *SliceUpIllegalIntegerPHI(PHINode &PN);155Instruction *visitPHINode(PHINode &PN);156Instruction *visitGetElementPtrInst(GetElementPtrInst &GEP);157Instruction *visitGEPOfGEP(GetElementPtrInst &GEP, GEPOperator *Src);158Instruction *visitAllocaInst(AllocaInst &AI);159Instruction *visitAllocSite(Instruction &FI);160Instruction *visitFree(CallInst &FI, Value *FreedOp);161Instruction *visitLoadInst(LoadInst &LI);162Instruction *visitStoreInst(StoreInst &SI);163Instruction *visitAtomicRMWInst(AtomicRMWInst &SI);164Instruction *visitUnconditionalBranchInst(BranchInst &BI);165Instruction *visitBranchInst(BranchInst &BI);166Instruction *visitFenceInst(FenceInst &FI);167Instruction *visitSwitchInst(SwitchInst &SI);168Instruction *visitReturnInst(ReturnInst &RI);169Instruction *visitUnreachableInst(UnreachableInst &I);170Instruction *171foldAggregateConstructionIntoAggregateReuse(InsertValueInst &OrigIVI);172Instruction *visitInsertValueInst(InsertValueInst &IV);173Instruction *visitInsertElementInst(InsertElementInst &IE);174Instruction *visitExtractElementInst(ExtractElementInst &EI);175Instruction *simplifyBinOpSplats(ShuffleVectorInst &SVI);176Instruction *visitShuffleVectorInst(ShuffleVectorInst &SVI);177Instruction *visitExtractValueInst(ExtractValueInst &EV);178Instruction *visitLandingPadInst(LandingPadInst &LI);179Instruction *visitVAEndInst(VAEndInst &I);180Value *pushFreezeToPreventPoisonFromPropagating(FreezeInst &FI);181bool freezeOtherUses(FreezeInst &FI);182Instruction *foldFreezeIntoRecurrence(FreezeInst &I, PHINode *PN);183Instruction *visitFreeze(FreezeInst &I);184185/// Specify what to return for unhandled instructions.186Instruction *visitInstruction(Instruction &I) { return nullptr; }187188/// True when DB dominates all uses of DI except UI.189/// UI must be in the same block as DI.190/// The routine checks that the DI parent and DB are different.191bool dominatesAllUses(const Instruction *DI, const Instruction *UI,192const BasicBlock *DB) const;193194/// Try to replace select with select operand SIOpd in SI-ICmp sequence.195bool replacedSelectWithOperand(SelectInst *SI, const ICmpInst *Icmp,196const unsigned SIOpd);197198LoadInst *combineLoadToNewType(LoadInst &LI, Type *NewTy,199const Twine &Suffix = "");200201KnownFPClass computeKnownFPClass(Value *Val, FastMathFlags FMF,202FPClassTest Interested = fcAllFlags,203const Instruction *CtxI = nullptr,204unsigned Depth = 0) const {205return llvm::computeKnownFPClass(206Val, FMF, Interested, Depth,207getSimplifyQuery().getWithInstruction(CtxI));208}209210KnownFPClass computeKnownFPClass(Value *Val,211FPClassTest Interested = fcAllFlags,212const Instruction *CtxI = nullptr,213unsigned Depth = 0) const {214return llvm::computeKnownFPClass(215Val, Interested, Depth, getSimplifyQuery().getWithInstruction(CtxI));216}217218/// Check if fmul \p MulVal, +0.0 will yield +0.0 (or signed zero is219/// ignorable).220bool fmulByZeroIsZero(Value *MulVal, FastMathFlags FMF,221const Instruction *CtxI) const;222223Constant *getLosslessTrunc(Constant *C, Type *TruncTy, unsigned ExtOp) {224Constant *TruncC = ConstantExpr::getTrunc(C, TruncTy);225Constant *ExtTruncC =226ConstantFoldCastOperand(ExtOp, TruncC, C->getType(), DL);227if (ExtTruncC && ExtTruncC == C)228return TruncC;229return nullptr;230}231232Constant *getLosslessUnsignedTrunc(Constant *C, Type *TruncTy) {233return getLosslessTrunc(C, TruncTy, Instruction::ZExt);234}235236Constant *getLosslessSignedTrunc(Constant *C, Type *TruncTy) {237return getLosslessTrunc(C, TruncTy, Instruction::SExt);238}239240std::optional<std::pair<Intrinsic::ID, SmallVector<Value *, 3>>>241convertOrOfShiftsToFunnelShift(Instruction &Or);242243private:244bool annotateAnyAllocSite(CallBase &Call, const TargetLibraryInfo *TLI);245bool isDesirableIntType(unsigned BitWidth) const;246bool shouldChangeType(unsigned FromBitWidth, unsigned ToBitWidth) const;247bool shouldChangeType(Type *From, Type *To) const;248Value *dyn_castNegVal(Value *V) const;249250/// Classify whether a cast is worth optimizing.251///252/// This is a helper to decide whether the simplification of253/// logic(cast(A), cast(B)) to cast(logic(A, B)) should be performed.254///255/// \param CI The cast we are interested in.256///257/// \return true if this cast actually results in any code being generated and258/// if it cannot already be eliminated by some other transformation.259bool shouldOptimizeCast(CastInst *CI);260261/// Try to optimize a sequence of instructions checking if an operation262/// on LHS and RHS overflows.263///264/// If this overflow check is done via one of the overflow check intrinsics,265/// then CtxI has to be the call instruction calling that intrinsic. If this266/// overflow check is done by arithmetic followed by a compare, then CtxI has267/// to be the arithmetic instruction.268///269/// If a simplification is possible, stores the simplified result of the270/// operation in OperationResult and result of the overflow check in271/// OverflowResult, and return true. If no simplification is possible,272/// returns false.273bool OptimizeOverflowCheck(Instruction::BinaryOps BinaryOp, bool IsSigned,274Value *LHS, Value *RHS,275Instruction &CtxI, Value *&OperationResult,276Constant *&OverflowResult);277278Instruction *visitCallBase(CallBase &Call);279Instruction *tryOptimizeCall(CallInst *CI);280bool transformConstExprCastCall(CallBase &Call);281Instruction *transformCallThroughTrampoline(CallBase &Call,282IntrinsicInst &Tramp);283284// Return (a, b) if (LHS, RHS) is known to be (a, b) or (b, a).285// Otherwise, return std::nullopt286// Currently it matches:287// - LHS = (select c, a, b), RHS = (select c, b, a)288// - LHS = (phi [a, BB0], [b, BB1]), RHS = (phi [b, BB0], [a, BB1])289// - LHS = min(a, b), RHS = max(a, b)290std::optional<std::pair<Value *, Value *>> matchSymmetricPair(Value *LHS,291Value *RHS);292293Value *simplifyMaskedLoad(IntrinsicInst &II);294Instruction *simplifyMaskedStore(IntrinsicInst &II);295Instruction *simplifyMaskedGather(IntrinsicInst &II);296Instruction *simplifyMaskedScatter(IntrinsicInst &II);297298/// Transform (zext icmp) to bitwise / integer operations in order to299/// eliminate it.300///301/// \param ICI The icmp of the (zext icmp) pair we are interested in.302/// \parem CI The zext of the (zext icmp) pair we are interested in.303///304/// \return null if the transformation cannot be performed. If the305/// transformation can be performed the new instruction that replaces the306/// (zext icmp) pair will be returned.307Instruction *transformZExtICmp(ICmpInst *Cmp, ZExtInst &Zext);308309Instruction *transformSExtICmp(ICmpInst *Cmp, SExtInst &Sext);310311bool willNotOverflowSignedAdd(const WithCache<const Value *> &LHS,312const WithCache<const Value *> &RHS,313const Instruction &CxtI) const {314return computeOverflowForSignedAdd(LHS, RHS, &CxtI) ==315OverflowResult::NeverOverflows;316}317318bool willNotOverflowUnsignedAdd(const WithCache<const Value *> &LHS,319const WithCache<const Value *> &RHS,320const Instruction &CxtI) const {321return computeOverflowForUnsignedAdd(LHS, RHS, &CxtI) ==322OverflowResult::NeverOverflows;323}324325bool willNotOverflowAdd(const Value *LHS, const Value *RHS,326const Instruction &CxtI, bool IsSigned) const {327return IsSigned ? willNotOverflowSignedAdd(LHS, RHS, CxtI)328: willNotOverflowUnsignedAdd(LHS, RHS, CxtI);329}330331bool willNotOverflowSignedSub(const Value *LHS, const Value *RHS,332const Instruction &CxtI) const {333return computeOverflowForSignedSub(LHS, RHS, &CxtI) ==334OverflowResult::NeverOverflows;335}336337bool willNotOverflowUnsignedSub(const Value *LHS, const Value *RHS,338const Instruction &CxtI) const {339return computeOverflowForUnsignedSub(LHS, RHS, &CxtI) ==340OverflowResult::NeverOverflows;341}342343bool willNotOverflowSub(const Value *LHS, const Value *RHS,344const Instruction &CxtI, bool IsSigned) const {345return IsSigned ? willNotOverflowSignedSub(LHS, RHS, CxtI)346: willNotOverflowUnsignedSub(LHS, RHS, CxtI);347}348349bool willNotOverflowSignedMul(const Value *LHS, const Value *RHS,350const Instruction &CxtI) const {351return computeOverflowForSignedMul(LHS, RHS, &CxtI) ==352OverflowResult::NeverOverflows;353}354355bool willNotOverflowUnsignedMul(const Value *LHS, const Value *RHS,356const Instruction &CxtI,357bool IsNSW = false) const {358return computeOverflowForUnsignedMul(LHS, RHS, &CxtI, IsNSW) ==359OverflowResult::NeverOverflows;360}361362bool willNotOverflowMul(const Value *LHS, const Value *RHS,363const Instruction &CxtI, bool IsSigned) const {364return IsSigned ? willNotOverflowSignedMul(LHS, RHS, CxtI)365: willNotOverflowUnsignedMul(LHS, RHS, CxtI);366}367368bool willNotOverflow(BinaryOperator::BinaryOps Opcode, const Value *LHS,369const Value *RHS, const Instruction &CxtI,370bool IsSigned) const {371switch (Opcode) {372case Instruction::Add: return willNotOverflowAdd(LHS, RHS, CxtI, IsSigned);373case Instruction::Sub: return willNotOverflowSub(LHS, RHS, CxtI, IsSigned);374case Instruction::Mul: return willNotOverflowMul(LHS, RHS, CxtI, IsSigned);375default: llvm_unreachable("Unexpected opcode for overflow query");376}377}378379Value *EmitGEPOffset(GEPOperator *GEP, bool RewriteGEP = false);380Instruction *scalarizePHI(ExtractElementInst &EI, PHINode *PN);381Instruction *foldBitcastExtElt(ExtractElementInst &ExtElt);382Instruction *foldCastedBitwiseLogic(BinaryOperator &I);383Instruction *foldFBinOpOfIntCasts(BinaryOperator &I);384// Should only be called by `foldFBinOpOfIntCasts`.385Instruction *foldFBinOpOfIntCastsFromSign(386BinaryOperator &BO, bool OpsFromSigned, std::array<Value *, 2> IntOps,387Constant *Op1FpC, SmallVectorImpl<WithCache<const Value *>> &OpsKnown);388Instruction *foldBinopOfSextBoolToSelect(BinaryOperator &I);389Instruction *narrowBinOp(TruncInst &Trunc);390Instruction *narrowMaskedBinOp(BinaryOperator &And);391Instruction *narrowMathIfNoOverflow(BinaryOperator &I);392Instruction *narrowFunnelShift(TruncInst &Trunc);393Instruction *optimizeBitCastFromPhi(CastInst &CI, PHINode *PN);394Instruction *matchSAddSubSat(IntrinsicInst &MinMax1);395Instruction *foldNot(BinaryOperator &I);396Instruction *foldBinOpOfDisplacedShifts(BinaryOperator &I);397398/// Determine if a pair of casts can be replaced by a single cast.399///400/// \param CI1 The first of a pair of casts.401/// \param CI2 The second of a pair of casts.402///403/// \return 0 if the cast pair cannot be eliminated, otherwise returns an404/// Instruction::CastOps value for a cast that can replace the pair, casting405/// CI1->getSrcTy() to CI2->getDstTy().406///407/// \see CastInst::isEliminableCastPair408Instruction::CastOps isEliminableCastPair(const CastInst *CI1,409const CastInst *CI2);410Value *simplifyIntToPtrRoundTripCast(Value *Val);411412Value *foldAndOrOfICmps(ICmpInst *LHS, ICmpInst *RHS, Instruction &I,413bool IsAnd, bool IsLogical = false);414Value *foldXorOfICmps(ICmpInst *LHS, ICmpInst *RHS, BinaryOperator &Xor);415416Value *foldEqOfParts(ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd);417418Value *foldAndOrOfICmpsUsingRanges(ICmpInst *ICmp1, ICmpInst *ICmp2,419bool IsAnd);420421/// Optimize (fcmp)&(fcmp) or (fcmp)|(fcmp).422/// NOTE: Unlike most of instcombine, this returns a Value which should423/// already be inserted into the function.424Value *foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS, bool IsAnd,425bool IsLogicalSelect = false);426427Instruction *foldLogicOfIsFPClass(BinaryOperator &Operator, Value *LHS,428Value *RHS);429430Instruction *431canonicalizeConditionalNegationViaMathToSelect(BinaryOperator &i);432433Value *foldAndOrOfICmpsOfAndWithPow2(ICmpInst *LHS, ICmpInst *RHS,434Instruction *CxtI, bool IsAnd,435bool IsLogical = false);436Value *matchSelectFromAndOr(Value *A, Value *B, Value *C, Value *D,437bool InvertFalseVal = false);438Value *getSelectCondition(Value *A, Value *B, bool ABIsTheSame);439440Instruction *foldLShrOverflowBit(BinaryOperator &I);441Instruction *foldExtractOfOverflowIntrinsic(ExtractValueInst &EV);442Instruction *foldIntrinsicWithOverflowCommon(IntrinsicInst *II);443Instruction *foldIntrinsicIsFPClass(IntrinsicInst &II);444Instruction *foldFPSignBitOps(BinaryOperator &I);445Instruction *foldFDivConstantDivisor(BinaryOperator &I);446447// Optimize one of these forms:448// and i1 Op, SI / select i1 Op, i1 SI, i1 false (if IsAnd = true)449// or i1 Op, SI / select i1 Op, i1 true, i1 SI (if IsAnd = false)450// into simplier select instruction using isImpliedCondition.451Instruction *foldAndOrOfSelectUsingImpliedCond(Value *Op, SelectInst &SI,452bool IsAnd);453454Instruction *hoistFNegAboveFMulFDiv(Value *FNegOp, Instruction &FMFSource);455456public:457/// Create and insert the idiom we use to indicate a block is unreachable458/// without having to rewrite the CFG from within InstCombine.459void CreateNonTerminatorUnreachable(Instruction *InsertAt) {460auto &Ctx = InsertAt->getContext();461auto *SI = new StoreInst(ConstantInt::getTrue(Ctx),462PoisonValue::get(PointerType::getUnqual(Ctx)),463/*isVolatile*/ false, Align(1));464InsertNewInstWith(SI, InsertAt->getIterator());465}466467/// Combiner aware instruction erasure.468///469/// When dealing with an instruction that has side effects or produces a void470/// value, we can't rely on DCE to delete the instruction. Instead, visit471/// methods should return the value returned by this function.472Instruction *eraseInstFromFunction(Instruction &I) override {473LLVM_DEBUG(dbgs() << "IC: ERASE " << I << '\n');474assert(I.use_empty() && "Cannot erase instruction that is used!");475salvageDebugInfo(I);476477// Make sure that we reprocess all operands now that we reduced their478// use counts.479SmallVector<Value *> Ops(I.operands());480Worklist.remove(&I);481DC.removeValue(&I);482I.eraseFromParent();483for (Value *Op : Ops)484Worklist.handleUseCountDecrement(Op);485MadeIRChange = true;486return nullptr; // Don't do anything with FI487}488489OverflowResult computeOverflow(490Instruction::BinaryOps BinaryOp, bool IsSigned,491Value *LHS, Value *RHS, Instruction *CxtI) const;492493/// Performs a few simplifications for operators which are associative494/// or commutative.495bool SimplifyAssociativeOrCommutative(BinaryOperator &I);496497/// Tries to simplify binary operations which some other binary498/// operation distributes over.499///500/// It does this by either by factorizing out common terms (eg "(A*B)+(A*C)"501/// -> "A*(B+C)") or expanding out if this results in simplifications (eg: "A502/// & (B | C) -> (A&B) | (A&C)" if this is a win). Returns the simplified503/// value, or null if it didn't simplify.504Value *foldUsingDistributiveLaws(BinaryOperator &I);505506/// Tries to simplify add operations using the definition of remainder.507///508/// The definition of remainder is X % C = X - (X / C ) * C. The add509/// expression X % C0 + (( X / C0 ) % C1) * C0 can be simplified to510/// X % (C0 * C1)511Value *SimplifyAddWithRemainder(BinaryOperator &I);512513// Binary Op helper for select operations where the expression can be514// efficiently reorganized.515Value *SimplifySelectsFeedingBinaryOp(BinaryOperator &I, Value *LHS,516Value *RHS);517518// If `I` has operand `(ctpop (not x))`, fold `I` with `(sub nuw nsw519// BitWidth(x), (ctpop x))`.520Instruction *tryFoldInstWithCtpopWithNot(Instruction *I);521522// (Binop1 (Binop2 (logic_shift X, C), C1), (logic_shift Y, C))523// -> (logic_shift (Binop1 (Binop2 X, inv_logic_shift(C1, C)), Y), C)524// (Binop1 (Binop2 (logic_shift X, Amt), Mask), (logic_shift Y, Amt))525// -> (BinOp (logic_shift (BinOp X, Y)), Mask)526Instruction *foldBinOpShiftWithShift(BinaryOperator &I);527528/// Tries to simplify binops of select and cast of the select condition.529///530/// (Binop (cast C), (select C, T, F))531/// -> (select C, C0, C1)532Instruction *foldBinOpOfSelectAndCastOfSelectCondition(BinaryOperator &I);533534/// This tries to simplify binary operations by factorizing out common terms535/// (e. g. "(A*B)+(A*C)" -> "A*(B+C)").536Value *tryFactorizationFolds(BinaryOperator &I);537538/// Match a select chain which produces one of three values based on whether539/// the LHS is less than, equal to, or greater than RHS respectively.540/// Return true if we matched a three way compare idiom. The LHS, RHS, Less,541/// Equal and Greater values are saved in the matching process and returned to542/// the caller.543bool matchThreeWayIntCompare(SelectInst *SI, Value *&LHS, Value *&RHS,544ConstantInt *&Less, ConstantInt *&Equal,545ConstantInt *&Greater);546547/// Attempts to replace I with a simpler value based on the demanded548/// bits.549Value *SimplifyDemandedUseBits(Instruction *I, const APInt &DemandedMask,550KnownBits &Known, unsigned Depth,551const SimplifyQuery &Q);552using InstCombiner::SimplifyDemandedBits;553bool SimplifyDemandedBits(Instruction *I, unsigned Op,554const APInt &DemandedMask, KnownBits &Known,555unsigned Depth, const SimplifyQuery &Q) override;556557/// Helper routine of SimplifyDemandedUseBits. It computes KnownZero/KnownOne558/// bits. It also tries to handle simplifications that can be done based on559/// DemandedMask, but without modifying the Instruction.560Value *SimplifyMultipleUseDemandedBits(Instruction *I,561const APInt &DemandedMask,562KnownBits &Known, unsigned Depth,563const SimplifyQuery &Q);564565/// Helper routine of SimplifyDemandedUseBits. It tries to simplify demanded566/// bit for "r1 = shr x, c1; r2 = shl r1, c2" instruction sequence.567Value *simplifyShrShlDemandedBits(568Instruction *Shr, const APInt &ShrOp1, Instruction *Shl,569const APInt &ShlOp1, const APInt &DemandedMask, KnownBits &Known);570571/// Tries to simplify operands to an integer instruction based on its572/// demanded bits.573bool SimplifyDemandedInstructionBits(Instruction &Inst);574bool SimplifyDemandedInstructionBits(Instruction &Inst, KnownBits &Known);575576Value *SimplifyDemandedVectorElts(Value *V, APInt DemandedElts,577APInt &PoisonElts, unsigned Depth = 0,578bool AllowMultipleUsers = false) override;579580/// Attempts to replace V with a simpler value based on the demanded581/// floating-point classes582Value *SimplifyDemandedUseFPClass(Value *V, FPClassTest DemandedMask,583KnownFPClass &Known, unsigned Depth,584Instruction *CxtI);585bool SimplifyDemandedFPClass(Instruction *I, unsigned Op,586FPClassTest DemandedMask, KnownFPClass &Known,587unsigned Depth = 0);588589/// Canonicalize the position of binops relative to shufflevector.590Instruction *foldVectorBinop(BinaryOperator &Inst);591Instruction *foldVectorSelect(SelectInst &Sel);592Instruction *foldSelectShuffle(ShuffleVectorInst &Shuf);593594/// Given a binary operator, cast instruction, or select which has a PHI node595/// as operand #0, see if we can fold the instruction into the PHI (which is596/// only possible if all operands to the PHI are constants).597Instruction *foldOpIntoPhi(Instruction &I, PHINode *PN);598599/// For a binary operator with 2 phi operands, try to hoist the binary600/// operation before the phi. This can result in fewer instructions in601/// patterns where at least one set of phi operands simplifies.602/// Example:603/// BB3: binop (phi [X, BB1], [C1, BB2]), (phi [Y, BB1], [C2, BB2])604/// -->605/// BB1: BO = binop X, Y606/// BB3: phi [BO, BB1], [(binop C1, C2), BB2]607Instruction *foldBinopWithPhiOperands(BinaryOperator &BO);608609/// Given an instruction with a select as one operand and a constant as the610/// other operand, try to fold the binary operator into the select arguments.611/// This also works for Cast instructions, which obviously do not have a612/// second operand.613Instruction *FoldOpIntoSelect(Instruction &Op, SelectInst *SI,614bool FoldWithMultiUse = false);615616/// This is a convenience wrapper function for the above two functions.617Instruction *foldBinOpIntoSelectOrPhi(BinaryOperator &I);618619Instruction *foldAddWithConstant(BinaryOperator &Add);620621Instruction *foldSquareSumInt(BinaryOperator &I);622Instruction *foldSquareSumFP(BinaryOperator &I);623624/// Try to rotate an operation below a PHI node, using PHI nodes for625/// its operands.626Instruction *foldPHIArgOpIntoPHI(PHINode &PN);627Instruction *foldPHIArgBinOpIntoPHI(PHINode &PN);628Instruction *foldPHIArgInsertValueInstructionIntoPHI(PHINode &PN);629Instruction *foldPHIArgExtractValueInstructionIntoPHI(PHINode &PN);630Instruction *foldPHIArgGEPIntoPHI(PHINode &PN);631Instruction *foldPHIArgLoadIntoPHI(PHINode &PN);632Instruction *foldPHIArgZextsIntoPHI(PHINode &PN);633Instruction *foldPHIArgIntToPtrToPHI(PHINode &PN);634635/// If an integer typed PHI has only one use which is an IntToPtr operation,636/// replace the PHI with an existing pointer typed PHI if it exists. Otherwise637/// insert a new pointer typed PHI and replace the original one.638bool foldIntegerTypedPHI(PHINode &PN);639640/// Helper function for FoldPHIArgXIntoPHI() to set debug location for the641/// folded operation.642void PHIArgMergedDebugLoc(Instruction *Inst, PHINode &PN);643644Instruction *foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,645ICmpInst::Predicate Cond, Instruction &I);646Instruction *foldSelectICmp(ICmpInst::Predicate Pred, SelectInst *SI,647Value *RHS, const ICmpInst &I);648bool foldAllocaCmp(AllocaInst *Alloca);649Instruction *foldCmpLoadFromIndexedGlobal(LoadInst *LI,650GetElementPtrInst *GEP,651GlobalVariable *GV, CmpInst &ICI,652ConstantInt *AndCst = nullptr);653Instruction *foldFCmpIntToFPConst(FCmpInst &I, Instruction *LHSI,654Constant *RHSC);655Instruction *foldICmpAddOpConst(Value *X, const APInt &C,656ICmpInst::Predicate Pred);657Instruction *foldICmpWithCastOp(ICmpInst &ICmp);658Instruction *foldICmpWithZextOrSext(ICmpInst &ICmp);659660Instruction *foldICmpUsingKnownBits(ICmpInst &Cmp);661Instruction *foldICmpWithDominatingICmp(ICmpInst &Cmp);662Instruction *foldICmpWithConstant(ICmpInst &Cmp);663Instruction *foldICmpUsingBoolRange(ICmpInst &I);664Instruction *foldICmpInstWithConstant(ICmpInst &Cmp);665Instruction *foldICmpInstWithConstantNotInt(ICmpInst &Cmp);666Instruction *foldICmpInstWithConstantAllowPoison(ICmpInst &Cmp,667const APInt &C);668Instruction *foldICmpBinOp(ICmpInst &Cmp, const SimplifyQuery &SQ);669Instruction *foldICmpWithMinMax(Instruction &I, MinMaxIntrinsic *MinMax,670Value *Z, ICmpInst::Predicate Pred);671Instruction *foldICmpEquality(ICmpInst &Cmp);672Instruction *foldIRemByPowerOfTwoToBitTest(ICmpInst &I);673Instruction *foldSignBitTest(ICmpInst &I);674Instruction *foldICmpWithZero(ICmpInst &Cmp);675676Value *foldMultiplicationOverflowCheck(ICmpInst &Cmp);677678Instruction *foldICmpBinOpWithConstant(ICmpInst &Cmp, BinaryOperator *BO,679const APInt &C);680Instruction *foldICmpSelectConstant(ICmpInst &Cmp, SelectInst *Select,681ConstantInt *C);682Instruction *foldICmpTruncConstant(ICmpInst &Cmp, TruncInst *Trunc,683const APInt &C);684Instruction *foldICmpTruncWithTruncOrExt(ICmpInst &Cmp,685const SimplifyQuery &Q);686Instruction *foldICmpAndConstant(ICmpInst &Cmp, BinaryOperator *And,687const APInt &C);688Instruction *foldICmpXorConstant(ICmpInst &Cmp, BinaryOperator *Xor,689const APInt &C);690Instruction *foldICmpOrConstant(ICmpInst &Cmp, BinaryOperator *Or,691const APInt &C);692Instruction *foldICmpMulConstant(ICmpInst &Cmp, BinaryOperator *Mul,693const APInt &C);694Instruction *foldICmpShlConstant(ICmpInst &Cmp, BinaryOperator *Shl,695const APInt &C);696Instruction *foldICmpShrConstant(ICmpInst &Cmp, BinaryOperator *Shr,697const APInt &C);698Instruction *foldICmpSRemConstant(ICmpInst &Cmp, BinaryOperator *UDiv,699const APInt &C);700Instruction *foldICmpUDivConstant(ICmpInst &Cmp, BinaryOperator *UDiv,701const APInt &C);702Instruction *foldICmpDivConstant(ICmpInst &Cmp, BinaryOperator *Div,703const APInt &C);704Instruction *foldICmpSubConstant(ICmpInst &Cmp, BinaryOperator *Sub,705const APInt &C);706Instruction *foldICmpAddConstant(ICmpInst &Cmp, BinaryOperator *Add,707const APInt &C);708Instruction *foldICmpAndConstConst(ICmpInst &Cmp, BinaryOperator *And,709const APInt &C1);710Instruction *foldICmpAndShift(ICmpInst &Cmp, BinaryOperator *And,711const APInt &C1, const APInt &C2);712Instruction *foldICmpXorShiftConst(ICmpInst &Cmp, BinaryOperator *Xor,713const APInt &C);714Instruction *foldICmpShrConstConst(ICmpInst &I, Value *ShAmt, const APInt &C1,715const APInt &C2);716Instruction *foldICmpShlConstConst(ICmpInst &I, Value *ShAmt, const APInt &C1,717const APInt &C2);718719Instruction *foldICmpBinOpEqualityWithConstant(ICmpInst &Cmp,720BinaryOperator *BO,721const APInt &C);722Instruction *foldICmpIntrinsicWithConstant(ICmpInst &ICI, IntrinsicInst *II,723const APInt &C);724Instruction *foldICmpEqIntrinsicWithConstant(ICmpInst &ICI, IntrinsicInst *II,725const APInt &C);726Instruction *foldICmpBitCast(ICmpInst &Cmp);727Instruction *foldICmpWithTrunc(ICmpInst &Cmp);728Instruction *foldICmpCommutative(ICmpInst::Predicate Pred, Value *Op0,729Value *Op1, ICmpInst &CxtI);730731// Helpers of visitSelectInst().732Instruction *foldSelectOfBools(SelectInst &SI);733Instruction *foldSelectExtConst(SelectInst &Sel);734Instruction *foldSelectOpOp(SelectInst &SI, Instruction *TI, Instruction *FI);735Instruction *foldSelectIntoOp(SelectInst &SI, Value *, Value *);736Instruction *foldSPFofSPF(Instruction *Inner, SelectPatternFlavor SPF1,737Value *A, Value *B, Instruction &Outer,738SelectPatternFlavor SPF2, Value *C);739Instruction *foldSelectInstWithICmp(SelectInst &SI, ICmpInst *ICI);740Instruction *foldSelectValueEquivalence(SelectInst &SI, ICmpInst &ICI);741bool replaceInInstruction(Value *V, Value *Old, Value *New,742unsigned Depth = 0);743744Value *insertRangeTest(Value *V, const APInt &Lo, const APInt &Hi,745bool isSigned, bool Inside);746bool mergeStoreIntoSuccessor(StoreInst &SI);747748/// Given an initial instruction, check to see if it is the root of a749/// bswap/bitreverse idiom. If so, return the equivalent bswap/bitreverse750/// intrinsic.751Instruction *matchBSwapOrBitReverse(Instruction &I, bool MatchBSwaps,752bool MatchBitReversals);753754Instruction *SimplifyAnyMemTransfer(AnyMemTransferInst *MI);755Instruction *SimplifyAnyMemSet(AnyMemSetInst *MI);756757Value *EvaluateInDifferentType(Value *V, Type *Ty, bool isSigned);758759bool tryToSinkInstruction(Instruction *I, BasicBlock *DestBlock);760void tryToSinkInstructionDbgValues(761Instruction *I, BasicBlock::iterator InsertPos, BasicBlock *SrcBlock,762BasicBlock *DestBlock, SmallVectorImpl<DbgVariableIntrinsic *> &DbgUsers);763void tryToSinkInstructionDbgVariableRecords(764Instruction *I, BasicBlock::iterator InsertPos, BasicBlock *SrcBlock,765BasicBlock *DestBlock, SmallVectorImpl<DbgVariableRecord *> &DPUsers);766767bool removeInstructionsBeforeUnreachable(Instruction &I);768void addDeadEdge(BasicBlock *From, BasicBlock *To,769SmallVectorImpl<BasicBlock *> &Worklist);770void handleUnreachableFrom(Instruction *I,771SmallVectorImpl<BasicBlock *> &Worklist);772void handlePotentiallyDeadBlocks(SmallVectorImpl<BasicBlock *> &Worklist);773void handlePotentiallyDeadSuccessors(BasicBlock *BB, BasicBlock *LiveSucc);774void freelyInvertAllUsersOf(Value *V, Value *IgnoredUser = nullptr);775};776777class Negator final {778/// Top-to-bottom, def-to-use negated instruction tree we produced.779SmallVector<Instruction *, NegatorMaxNodesSSO> NewInstructions;780781using BuilderTy = IRBuilder<TargetFolder, IRBuilderCallbackInserter>;782BuilderTy Builder;783784const bool IsTrulyNegation;785786SmallDenseMap<Value *, Value *> NegationsCache;787788Negator(LLVMContext &C, const DataLayout &DL, bool IsTrulyNegation);789790#if LLVM_ENABLE_STATS791unsigned NumValuesVisitedInThisNegator = 0;792~Negator();793#endif794795using Result = std::pair<ArrayRef<Instruction *> /*NewInstructions*/,796Value * /*NegatedRoot*/>;797798std::array<Value *, 2> getSortedOperandsOfBinOp(Instruction *I);799800[[nodiscard]] Value *visitImpl(Value *V, bool IsNSW, unsigned Depth);801802[[nodiscard]] Value *negate(Value *V, bool IsNSW, unsigned Depth);803804/// Recurse depth-first and attempt to sink the negation.805/// FIXME: use worklist?806[[nodiscard]] std::optional<Result> run(Value *Root, bool IsNSW);807808Negator(const Negator &) = delete;809Negator(Negator &&) = delete;810Negator &operator=(const Negator &) = delete;811Negator &operator=(Negator &&) = delete;812813public:814/// Attempt to negate \p Root. Retuns nullptr if negation can't be performed,815/// otherwise returns negated value.816[[nodiscard]] static Value *Negate(bool LHSIsZero, bool IsNSW, Value *Root,817InstCombinerImpl &IC);818};819820} // end namespace llvm821822#undef DEBUG_TYPE823824#endif // LLVM_LIB_TRANSFORMS_INSTCOMBINE_INSTCOMBINEINTERNAL_H825826827