//===- InstCombineSimplifyDemanded.cpp ------------------------------------===// // // 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 // //===----------------------------------------------------------------------===// // // This file contains logic for simplifying instructions based on information // about how they are used. // //===----------------------------------------------------------------------===// #include "InstCombineInternal.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/PatternMatch.h" #include "llvm/Support/KnownBits.h" #include "llvm/Transforms/InstCombine/InstCombiner.h" usingnamespacellvm; usingnamespacellvm::PatternMatch; #define DEBUG_TYPE … static cl::opt<bool> VerifyKnownBits("instcombine-verify-known-bits", cl::desc("Verify that computeKnownBits() and " "SimplifyDemandedBits() are consistent"), cl::Hidden, cl::init(false)); /// Check to see if the specified operand of the specified instruction is a /// constant integer. If so, check to see if there are any bits set in the /// constant that are not demanded. If so, shrink the constant and return true. static bool ShrinkDemandedConstant(Instruction *I, unsigned OpNo, const APInt &Demanded) { … } /// Returns the bitwidth of the given scalar or pointer type. For vector types, /// returns the element type's bitwidth. static unsigned getBitWidth(Type *Ty, const DataLayout &DL) { … } /// Inst is an integer instruction that SimplifyDemandedBits knows about. See if /// the instruction has any properties that allow us to simplify its operands. bool InstCombinerImpl::SimplifyDemandedInstructionBits(Instruction &Inst, KnownBits &Known) { … } /// Inst is an integer instruction that SimplifyDemandedBits knows about. See if /// the instruction has any properties that allow us to simplify its operands. bool InstCombinerImpl::SimplifyDemandedInstructionBits(Instruction &Inst) { … } /// This form of SimplifyDemandedBits simplifies the specified instruction /// operand if possible, updating it in place. It returns true if it made any /// change and false otherwise. bool InstCombinerImpl::SimplifyDemandedBits(Instruction *I, unsigned OpNo, const APInt &DemandedMask, KnownBits &Known, unsigned Depth, const SimplifyQuery &Q) { … } /// This function attempts to replace V with a simpler value based on the /// demanded bits. When this function is called, it is known that only the bits /// set in DemandedMask of the result of V are ever used downstream. /// Consequently, depending on the mask and V, it may be possible to replace V /// with a constant or one of its operands. In such cases, this function does /// the replacement and returns true. In all other cases, it returns false after /// analyzing the expression and setting KnownOne and known to be one in the /// expression. Known.Zero contains all the bits that are known to be zero in /// the expression. These are provided to potentially allow the caller (which /// might recursively be SimplifyDemandedBits itself) to simplify the /// expression. /// Known.One and Known.Zero always follow the invariant that: /// Known.One & Known.Zero == 0. /// That is, a bit can't be both 1 and 0. The bits in Known.One and Known.Zero /// are accurate even for bits not in DemandedMask. Note /// also that the bitwidth of V, DemandedMask, Known.Zero and Known.One must all /// be the same. /// /// This returns null if it did not change anything and it permits no /// simplification. This returns V itself if it did some simplification of V's /// operands based on the information about what bits are demanded. This returns /// some other non-null value if it found out that V is equal to another value /// in the context where the specified bits are demanded, but not for all users. Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I, const APInt &DemandedMask, KnownBits &Known, unsigned Depth, const SimplifyQuery &Q) { … } /// Helper routine of SimplifyDemandedUseBits. It computes Known /// bits. It also tries to handle simplifications that can be done based on /// DemandedMask, but without modifying the Instruction. Value *InstCombinerImpl::SimplifyMultipleUseDemandedBits( Instruction *I, const APInt &DemandedMask, KnownBits &Known, unsigned Depth, const SimplifyQuery &Q) { … } /// Helper routine of SimplifyDemandedUseBits. It tries to simplify /// "E1 = (X lsr C1) << C2", where the C1 and C2 are constant, into /// "E2 = X << (C2 - C1)" or "E2 = X >> (C1 - C2)", depending on the sign /// of "C2-C1". /// /// Suppose E1 and E2 are generally different in bits S={bm, bm+1, /// ..., bn}, without considering the specific value X is holding. /// This transformation is legal iff one of following conditions is hold: /// 1) All the bit in S are 0, in this case E1 == E2. /// 2) We don't care those bits in S, per the input DemandedMask. /// 3) Combination of 1) and 2). Some bits in S are 0, and we don't care the /// rest bits. /// /// Currently we only test condition 2). /// /// As with SimplifyDemandedUseBits, it returns NULL if the simplification was /// not successful. Value *InstCombinerImpl::simplifyShrShlDemandedBits( Instruction *Shr, const APInt &ShrOp1, Instruction *Shl, const APInt &ShlOp1, const APInt &DemandedMask, KnownBits &Known) { … } /// The specified value produces a vector with any number of elements. /// This method analyzes which elements of the operand are poison and /// returns that information in PoisonElts. /// /// DemandedElts contains the set of elements that are actually used by the /// caller, and by default (AllowMultipleUsers equals false) the value is /// simplified only if it has a single caller. If AllowMultipleUsers is set /// to true, DemandedElts refers to the union of sets of elements that are /// used by all callers. /// /// If the information about demanded elements can be used to simplify the /// operation, the operation is simplified, then the resultant value is /// returned. This returns null if no change was made. Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, APInt &PoisonElts, unsigned Depth, bool AllowMultipleUsers) { … } /// For floating-point classes that resolve to a single bit pattern, return that /// value. static Constant *getFPClassConstant(Type *Ty, FPClassTest Mask) { … } Value *InstCombinerImpl::SimplifyDemandedUseFPClass( Value *V, const FPClassTest DemandedMask, KnownFPClass &Known, unsigned Depth, Instruction *CxtI) { … } bool InstCombinerImpl::SimplifyDemandedFPClass(Instruction *I, unsigned OpNo, FPClassTest DemandedMask, KnownFPClass &Known, unsigned Depth) { … }