123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- InstCombiner.h - InstCombine implementation --------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- /// \file
- ///
- /// This file provides the interface for the instcombine pass implementation.
- /// The interface is used for generic transformations in this folder and
- /// target specific combinations in the targets.
- /// The visitor implementation is in \c InstCombinerImpl in
- /// \c InstCombineInternal.h.
- ///
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_TRANSFORMS_INSTCOMBINE_INSTCOMBINER_H
- #define LLVM_TRANSFORMS_INSTCOMBINE_INSTCOMBINER_H
- #include "llvm/Analysis/InstructionSimplify.h"
- #include "llvm/Analysis/TargetFolder.h"
- #include "llvm/Analysis/ValueTracking.h"
- #include "llvm/IR/IRBuilder.h"
- #include "llvm/IR/PatternMatch.h"
- #include "llvm/Support/Debug.h"
- #include "llvm/Support/KnownBits.h"
- #include <cassert>
- #define DEBUG_TYPE "instcombine"
- #include "llvm/Transforms/Utils/InstructionWorklist.h"
- namespace llvm {
- class AAResults;
- class AssumptionCache;
- class ProfileSummaryInfo;
- class TargetLibraryInfo;
- class TargetTransformInfo;
- /// The core instruction combiner logic.
- ///
- /// This class provides both the logic to recursively visit instructions and
- /// combine them.
- class LLVM_LIBRARY_VISIBILITY InstCombiner {
- /// Only used to call target specific intrinsic combining.
- /// It must **NOT** be used for any other purpose, as InstCombine is a
- /// target-independent canonicalization transform.
- TargetTransformInfo &TTI;
- public:
- /// Maximum size of array considered when transforming.
- uint64_t MaxArraySizeForCombine = 0;
- /// An IRBuilder that automatically inserts new instructions into the
- /// worklist.
- using BuilderTy = IRBuilder<TargetFolder, IRBuilderCallbackInserter>;
- BuilderTy &Builder;
- protected:
- /// A worklist of the instructions that need to be simplified.
- InstructionWorklist &Worklist;
- // Mode in which we are running the combiner.
- const bool MinimizeSize;
- AAResults *AA;
- // Required analyses.
- AssumptionCache &AC;
- TargetLibraryInfo &TLI;
- DominatorTree &DT;
- const DataLayout &DL;
- const SimplifyQuery SQ;
- OptimizationRemarkEmitter &ORE;
- BlockFrequencyInfo *BFI;
- ProfileSummaryInfo *PSI;
- // Optional analyses. When non-null, these can both be used to do better
- // combining and will be updated to reflect any changes.
- LoopInfo *LI;
- bool MadeIRChange = false;
- public:
- InstCombiner(InstructionWorklist &Worklist, BuilderTy &Builder,
- bool MinimizeSize, AAResults *AA, AssumptionCache &AC,
- TargetLibraryInfo &TLI, TargetTransformInfo &TTI,
- DominatorTree &DT, OptimizationRemarkEmitter &ORE,
- BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI,
- const DataLayout &DL, LoopInfo *LI)
- : TTI(TTI), Builder(Builder), Worklist(Worklist),
- MinimizeSize(MinimizeSize), AA(AA), AC(AC), TLI(TLI), DT(DT), DL(DL),
- SQ(DL, &TLI, &DT, &AC), ORE(ORE), BFI(BFI), PSI(PSI), LI(LI) {}
- virtual ~InstCombiner() = default;
- /// Return the source operand of a potentially bitcasted value while
- /// optionally checking if it has one use. If there is no bitcast or the one
- /// use check is not met, return the input value itself.
- static Value *peekThroughBitcast(Value *V, bool OneUseOnly = false) {
- if (auto *BitCast = dyn_cast<BitCastInst>(V))
- if (!OneUseOnly || BitCast->hasOneUse())
- return BitCast->getOperand(0);
- // V is not a bitcast or V has more than one use and OneUseOnly is true.
- return V;
- }
- /// Assign a complexity or rank value to LLVM Values. This is used to reduce
- /// the amount of pattern matching needed for compares and commutative
- /// instructions. For example, if we have:
- /// icmp ugt X, Constant
- /// or
- /// xor (add X, Constant), cast Z
- ///
- /// We do not have to consider the commuted variants of these patterns because
- /// canonicalization based on complexity guarantees the above ordering.
- ///
- /// This routine maps IR values to various complexity ranks:
- /// 0 -> undef
- /// 1 -> Constants
- /// 2 -> Other non-instructions
- /// 3 -> Arguments
- /// 4 -> Cast and (f)neg/not instructions
- /// 5 -> Other instructions
- static unsigned getComplexity(Value *V) {
- if (isa<Instruction>(V)) {
- if (isa<CastInst>(V) || match(V, m_Neg(PatternMatch::m_Value())) ||
- match(V, m_Not(PatternMatch::m_Value())) ||
- match(V, m_FNeg(PatternMatch::m_Value())))
- return 4;
- return 5;
- }
- if (isa<Argument>(V))
- return 3;
- return isa<Constant>(V) ? (isa<UndefValue>(V) ? 0 : 1) : 2;
- }
- /// Predicate canonicalization reduces the number of patterns that need to be
- /// matched by other transforms. For example, we may swap the operands of a
- /// conditional branch or select to create a compare with a canonical
- /// (inverted) predicate which is then more likely to be matched with other
- /// values.
- static bool isCanonicalPredicate(CmpInst::Predicate Pred) {
- switch (Pred) {
- case CmpInst::ICMP_NE:
- case CmpInst::ICMP_ULE:
- case CmpInst::ICMP_SLE:
- case CmpInst::ICMP_UGE:
- case CmpInst::ICMP_SGE:
- // TODO: There are 16 FCMP predicates. Should others be (not) canonical?
- case CmpInst::FCMP_ONE:
- case CmpInst::FCMP_OLE:
- case CmpInst::FCMP_OGE:
- return false;
- default:
- return true;
- }
- }
- /// Given an exploded icmp instruction, return true if the comparison only
- /// checks the sign bit. If it only checks the sign bit, set TrueIfSigned if
- /// the result of the comparison is true when the input value is signed.
- static bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS,
- bool &TrueIfSigned) {
- switch (Pred) {
- case ICmpInst::ICMP_SLT: // True if LHS s< 0
- TrueIfSigned = true;
- return RHS.isZero();
- case ICmpInst::ICMP_SLE: // True if LHS s<= -1
- TrueIfSigned = true;
- return RHS.isAllOnes();
- case ICmpInst::ICMP_SGT: // True if LHS s> -1
- TrueIfSigned = false;
- return RHS.isAllOnes();
- case ICmpInst::ICMP_SGE: // True if LHS s>= 0
- TrueIfSigned = false;
- return RHS.isZero();
- case ICmpInst::ICMP_UGT:
- // True if LHS u> RHS and RHS == sign-bit-mask - 1
- TrueIfSigned = true;
- return RHS.isMaxSignedValue();
- case ICmpInst::ICMP_UGE:
- // True if LHS u>= RHS and RHS == sign-bit-mask (2^7, 2^15, 2^31, etc)
- TrueIfSigned = true;
- return RHS.isMinSignedValue();
- case ICmpInst::ICMP_ULT:
- // True if LHS u< RHS and RHS == sign-bit-mask (2^7, 2^15, 2^31, etc)
- TrueIfSigned = false;
- return RHS.isMinSignedValue();
- case ICmpInst::ICMP_ULE:
- // True if LHS u<= RHS and RHS == sign-bit-mask - 1
- TrueIfSigned = false;
- return RHS.isMaxSignedValue();
- default:
- return false;
- }
- }
- /// Add one to a Constant
- static Constant *AddOne(Constant *C) {
- return ConstantExpr::getAdd(C, ConstantInt::get(C->getType(), 1));
- }
- /// Subtract one from a Constant
- static Constant *SubOne(Constant *C) {
- return ConstantExpr::getSub(C, ConstantInt::get(C->getType(), 1));
- }
- std::optional<std::pair<
- CmpInst::Predicate,
- Constant *>> static getFlippedStrictnessPredicateAndConstant(CmpInst::
- Predicate
- Pred,
- Constant *C);
- static bool shouldAvoidAbsorbingNotIntoSelect(const SelectInst &SI) {
- // a ? b : false and a ? true : b are the canonical form of logical and/or.
- // This includes !a ? b : false and !a ? true : b. Absorbing the not into
- // the select by swapping operands would break recognition of this pattern
- // in other analyses, so don't do that.
- return match(&SI, PatternMatch::m_LogicalAnd(PatternMatch::m_Value(),
- PatternMatch::m_Value())) ||
- match(&SI, PatternMatch::m_LogicalOr(PatternMatch::m_Value(),
- PatternMatch::m_Value()));
- }
- /// Return true if the specified value is free to invert (apply ~ to).
- /// This happens in cases where the ~ can be eliminated. If WillInvertAllUses
- /// is true, work under the assumption that the caller intends to remove all
- /// uses of V and only keep uses of ~V.
- ///
- /// See also: canFreelyInvertAllUsersOf()
- static bool isFreeToInvert(Value *V, bool WillInvertAllUses) {
- // ~(~(X)) -> X.
- if (match(V, m_Not(PatternMatch::m_Value())))
- return true;
- // Constants can be considered to be not'ed values.
- if (match(V, PatternMatch::m_AnyIntegralConstant()))
- return true;
- // Compares can be inverted if all of their uses are being modified to use
- // the ~V.
- if (isa<CmpInst>(V))
- return WillInvertAllUses;
- // If `V` is of the form `A + Constant` then `-1 - V` can be folded into
- // `(-1 - Constant) - A` if we are willing to invert all of the uses.
- if (match(V, m_Add(PatternMatch::m_Value(), PatternMatch::m_ImmConstant())))
- return WillInvertAllUses;
- // If `V` is of the form `Constant - A` then `-1 - V` can be folded into
- // `A + (-1 - Constant)` if we are willing to invert all of the uses.
- if (match(V, m_Sub(PatternMatch::m_ImmConstant(), PatternMatch::m_Value())))
- return WillInvertAllUses;
- // Selects with invertible operands are freely invertible
- if (match(V,
- m_Select(PatternMatch::m_Value(), m_Not(PatternMatch::m_Value()),
- m_Not(PatternMatch::m_Value()))))
- return WillInvertAllUses;
- // Min/max may be in the form of intrinsics, so handle those identically
- // to select patterns.
- if (match(V, m_MaxOrMin(m_Not(PatternMatch::m_Value()),
- m_Not(PatternMatch::m_Value()))))
- return WillInvertAllUses;
- return false;
- }
- /// Given i1 V, can every user of V be freely adapted if V is changed to !V ?
- /// InstCombine's freelyInvertAllUsersOf() must be kept in sync with this fn.
- /// NOTE: for Instructions only!
- ///
- /// See also: isFreeToInvert()
- static bool canFreelyInvertAllUsersOf(Instruction *V, Value *IgnoredUser) {
- // Look at every user of V.
- for (Use &U : V->uses()) {
- if (U.getUser() == IgnoredUser)
- continue; // Don't consider this user.
- auto *I = cast<Instruction>(U.getUser());
- switch (I->getOpcode()) {
- case Instruction::Select:
- if (U.getOperandNo() != 0) // Only if the value is used as select cond.
- return false;
- if (shouldAvoidAbsorbingNotIntoSelect(*cast<SelectInst>(I)))
- return false;
- break;
- case Instruction::Br:
- assert(U.getOperandNo() == 0 && "Must be branching on that value.");
- break; // Free to invert by swapping true/false values/destinations.
- case Instruction::Xor: // Can invert 'xor' if it's a 'not', by ignoring
- // it.
- if (!match(I, m_Not(PatternMatch::m_Value())))
- return false; // Not a 'not'.
- break;
- default:
- return false; // Don't know, likely not freely invertible.
- }
- // So far all users were free to invert...
- }
- return true; // Can freely invert all users!
- }
- /// Some binary operators require special handling to avoid poison and
- /// undefined behavior. If a constant vector has undef elements, replace those
- /// undefs with identity constants if possible because those are always safe
- /// to execute. If no identity constant exists, replace undef with some other
- /// safe constant.
- static Constant *
- getSafeVectorConstantForBinop(BinaryOperator::BinaryOps Opcode, Constant *In,
- bool IsRHSConstant) {
- auto *InVTy = cast<FixedVectorType>(In->getType());
- Type *EltTy = InVTy->getElementType();
- auto *SafeC = ConstantExpr::getBinOpIdentity(Opcode, EltTy, IsRHSConstant);
- if (!SafeC) {
- // TODO: Should this be available as a constant utility function? It is
- // similar to getBinOpAbsorber().
- if (IsRHSConstant) {
- switch (Opcode) {
- case Instruction::SRem: // X % 1 = 0
- case Instruction::URem: // X %u 1 = 0
- SafeC = ConstantInt::get(EltTy, 1);
- break;
- case Instruction::FRem: // X % 1.0 (doesn't simplify, but it is safe)
- SafeC = ConstantFP::get(EltTy, 1.0);
- break;
- default:
- llvm_unreachable(
- "Only rem opcodes have no identity constant for RHS");
- }
- } else {
- switch (Opcode) {
- case Instruction::Shl: // 0 << X = 0
- case Instruction::LShr: // 0 >>u X = 0
- case Instruction::AShr: // 0 >> X = 0
- case Instruction::SDiv: // 0 / X = 0
- case Instruction::UDiv: // 0 /u X = 0
- case Instruction::SRem: // 0 % X = 0
- case Instruction::URem: // 0 %u X = 0
- case Instruction::Sub: // 0 - X (doesn't simplify, but it is safe)
- case Instruction::FSub: // 0.0 - X (doesn't simplify, but it is safe)
- case Instruction::FDiv: // 0.0 / X (doesn't simplify, but it is safe)
- case Instruction::FRem: // 0.0 % X = 0
- SafeC = Constant::getNullValue(EltTy);
- break;
- default:
- llvm_unreachable("Expected to find identity constant for opcode");
- }
- }
- }
- assert(SafeC && "Must have safe constant for binop");
- unsigned NumElts = InVTy->getNumElements();
- SmallVector<Constant *, 16> Out(NumElts);
- for (unsigned i = 0; i != NumElts; ++i) {
- Constant *C = In->getAggregateElement(i);
- Out[i] = isa<UndefValue>(C) ? SafeC : C;
- }
- return ConstantVector::get(Out);
- }
- void addToWorklist(Instruction *I) { Worklist.push(I); }
- AssumptionCache &getAssumptionCache() const { return AC; }
- TargetLibraryInfo &getTargetLibraryInfo() const { return TLI; }
- DominatorTree &getDominatorTree() const { return DT; }
- const DataLayout &getDataLayout() const { return DL; }
- const SimplifyQuery &getSimplifyQuery() const { return SQ; }
- OptimizationRemarkEmitter &getOptimizationRemarkEmitter() const {
- return ORE;
- }
- BlockFrequencyInfo *getBlockFrequencyInfo() const { return BFI; }
- ProfileSummaryInfo *getProfileSummaryInfo() const { return PSI; }
- LoopInfo *getLoopInfo() const { return LI; }
- // Call target specific combiners
- std::optional<Instruction *> targetInstCombineIntrinsic(IntrinsicInst &II);
- std::optional<Value *>
- targetSimplifyDemandedUseBitsIntrinsic(IntrinsicInst &II, APInt DemandedMask,
- KnownBits &Known,
- bool &KnownBitsComputed);
- std::optional<Value *> targetSimplifyDemandedVectorEltsIntrinsic(
- IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
- APInt &UndefElts2, APInt &UndefElts3,
- std::function<void(Instruction *, unsigned, APInt, APInt &)>
- SimplifyAndSetOp);
- /// Inserts an instruction \p New before instruction \p Old
- ///
- /// Also adds the new instruction to the worklist and returns \p New so that
- /// it is suitable for use as the return from the visitation patterns.
- Instruction *InsertNewInstBefore(Instruction *New, Instruction &Old) {
- assert(New && !New->getParent() &&
- "New instruction already inserted into a basic block!");
- BasicBlock *BB = Old.getParent();
- New->insertInto(BB, Old.getIterator()); // Insert inst
- Worklist.add(New);
- return New;
- }
- /// Same as InsertNewInstBefore, but also sets the debug loc.
- Instruction *InsertNewInstWith(Instruction *New, Instruction &Old) {
- New->setDebugLoc(Old.getDebugLoc());
- return InsertNewInstBefore(New, Old);
- }
- /// A combiner-aware RAUW-like routine.
- ///
- /// This method is to be used when an instruction is found to be dead,
- /// replaceable with another preexisting expression. Here we add all uses of
- /// I to the worklist, replace all uses of I with the new value, then return
- /// I, so that the inst combiner will know that I was modified.
- Instruction *replaceInstUsesWith(Instruction &I, Value *V) {
- // If there are no uses to replace, then we return nullptr to indicate that
- // no changes were made to the program.
- if (I.use_empty()) return nullptr;
- Worklist.pushUsersToWorkList(I); // Add all modified instrs to worklist.
- // If we are replacing the instruction with itself, this must be in a
- // segment of unreachable code, so just clobber the instruction.
- if (&I == V)
- V = PoisonValue::get(I.getType());
- LLVM_DEBUG(dbgs() << "IC: Replacing " << I << "\n"
- << " with " << *V << '\n');
- // If V is a new unnamed instruction, take the name from the old one.
- if (V->use_empty() && isa<Instruction>(V) && !V->hasName() && I.hasName())
- V->takeName(&I);
- I.replaceAllUsesWith(V);
- return &I;
- }
- /// Replace operand of instruction and add old operand to the worklist.
- Instruction *replaceOperand(Instruction &I, unsigned OpNum, Value *V) {
- Worklist.addValue(I.getOperand(OpNum));
- I.setOperand(OpNum, V);
- return &I;
- }
- /// Replace use and add the previously used value to the worklist.
- void replaceUse(Use &U, Value *NewValue) {
- Worklist.addValue(U);
- U = NewValue;
- }
- /// Combiner aware instruction erasure.
- ///
- /// When dealing with an instruction that has side effects or produces a void
- /// value, we can't rely on DCE to delete the instruction. Instead, visit
- /// methods should return the value returned by this function.
- virtual Instruction *eraseInstFromFunction(Instruction &I) = 0;
- void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth,
- const Instruction *CxtI) const {
- llvm::computeKnownBits(V, Known, DL, Depth, &AC, CxtI, &DT);
- }
- KnownBits computeKnownBits(const Value *V, unsigned Depth,
- const Instruction *CxtI) const {
- return llvm::computeKnownBits(V, DL, Depth, &AC, CxtI, &DT);
- }
- bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero = false,
- unsigned Depth = 0,
- const Instruction *CxtI = nullptr) {
- return llvm::isKnownToBeAPowerOfTwo(V, DL, OrZero, Depth, &AC, CxtI, &DT);
- }
- bool MaskedValueIsZero(const Value *V, const APInt &Mask, unsigned Depth = 0,
- const Instruction *CxtI = nullptr) const {
- return llvm::MaskedValueIsZero(V, Mask, DL, Depth, &AC, CxtI, &DT);
- }
- unsigned ComputeNumSignBits(const Value *Op, unsigned Depth = 0,
- const Instruction *CxtI = nullptr) const {
- return llvm::ComputeNumSignBits(Op, DL, Depth, &AC, CxtI, &DT);
- }
- unsigned ComputeMaxSignificantBits(const Value *Op, unsigned Depth = 0,
- const Instruction *CxtI = nullptr) const {
- return llvm::ComputeMaxSignificantBits(Op, DL, Depth, &AC, CxtI, &DT);
- }
- OverflowResult computeOverflowForUnsignedMul(const Value *LHS,
- const Value *RHS,
- const Instruction *CxtI) const {
- return llvm::computeOverflowForUnsignedMul(LHS, RHS, DL, &AC, CxtI, &DT);
- }
- OverflowResult computeOverflowForSignedMul(const Value *LHS, const Value *RHS,
- const Instruction *CxtI) const {
- return llvm::computeOverflowForSignedMul(LHS, RHS, DL, &AC, CxtI, &DT);
- }
- OverflowResult computeOverflowForUnsignedAdd(const Value *LHS,
- const Value *RHS,
- const Instruction *CxtI) const {
- return llvm::computeOverflowForUnsignedAdd(LHS, RHS, DL, &AC, CxtI, &DT);
- }
- OverflowResult computeOverflowForSignedAdd(const Value *LHS, const Value *RHS,
- const Instruction *CxtI) const {
- return llvm::computeOverflowForSignedAdd(LHS, RHS, DL, &AC, CxtI, &DT);
- }
- OverflowResult computeOverflowForUnsignedSub(const Value *LHS,
- const Value *RHS,
- const Instruction *CxtI) const {
- return llvm::computeOverflowForUnsignedSub(LHS, RHS, DL, &AC, CxtI, &DT);
- }
- OverflowResult computeOverflowForSignedSub(const Value *LHS, const Value *RHS,
- const Instruction *CxtI) const {
- return llvm::computeOverflowForSignedSub(LHS, RHS, DL, &AC, CxtI, &DT);
- }
- virtual bool SimplifyDemandedBits(Instruction *I, unsigned OpNo,
- const APInt &DemandedMask, KnownBits &Known,
- unsigned Depth = 0) = 0;
- virtual Value *
- SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, APInt &UndefElts,
- unsigned Depth = 0,
- bool AllowMultipleUsers = false) = 0;
- };
- } // namespace llvm
- #undef DEBUG_TYPE
- #endif
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|