mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-23 14:25:07 +00:00
Make use of @llvm.assume in ValueTracking (computeKnownBits, etc.)
This change, which allows @llvm.assume to be used from within computeKnownBits (and other associated functions in ValueTracking), adds some (optional) parameters to computeKnownBits and friends. These functions now (optionally) take a "context" instruction pointer, an AssumptionTracker pointer, and also a DomTree pointer, and most of the changes are just to pass this new information when it is easily available from InstSimplify, InstCombine, etc. As explained below, the significant conceptual change is that known properties of a value might depend on the control-flow location of the use (because we care that the @llvm.assume dominates the use because assumptions have control-flow dependencies). This means that, when we ask if bits are known in a value, we might get different answers for different uses. The significant changes are all in ValueTracking. Two main changes: First, as with the rest of the code, new parameters need to be passed around. To make this easier, I grouped them into a structure, and I made internal static versions of the relevant functions that take this structure as a parameter. The new code does as you might expect, it looks for @llvm.assume calls that make use of the value we're trying to learn something about (often indirectly), attempts to pattern match that expression, and uses the result if successful. By making use of the AssumptionTracker, the process of finding @llvm.assume calls is not expensive. Part of the structure being passed around inside ValueTracking is a set of already-considered @llvm.assume calls. This is to prevent a query using, for example, the assume(a == b), to recurse on itself. The context and DT params are used to find applicable assumptions. An assumption needs to dominate the context instruction, or come after it deterministically. In this latter case we only handle the specific case where both the assumption and the context instruction are in the same block, and we need to exclude assumptions from being used to simplify their own ephemeral values (those which contribute only to the assumption) because otherwise the assumption would prove its feeding comparison trivial and would be removed. This commit adds the plumbing and the logic for a simple masked-bit propagation (just enough to write a regression test). Future commits add more patterns (and, correspondingly, more regression tests). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217342 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
namespace llvm {
|
||||
template<typename T>
|
||||
class ArrayRef;
|
||||
class AssumptionTracker;
|
||||
class DominatorTree;
|
||||
class Instruction;
|
||||
class DataLayout;
|
||||
@@ -50,28 +51,36 @@ namespace llvm {
|
||||
Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifySubInst - Given operands for a Sub, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an FAdd, see if we can fold the result. If not, this
|
||||
/// returns null.
|
||||
Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an FSub, see if we can fold the result. If not, this
|
||||
/// returns null.
|
||||
Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an FMul, see if we can fold the result. If not, this
|
||||
/// returns null.
|
||||
@@ -79,121 +88,157 @@ namespace llvm {
|
||||
FastMathFlags FMF,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifyMulInst - Given operands for a Mul, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifySDivInst - Given operands for an SDiv, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifySDivInst(Value *LHS, Value *RHS,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifyUDivInst - Given operands for a UDiv, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyUDivInst(Value *LHS, Value *RHS,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifyFDivInst - Given operands for an FDiv, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyFDivInst(Value *LHS, Value *RHS,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifySRemInst - Given operands for an SRem, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifySRemInst(Value *LHS, Value *RHS,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifyURemInst - Given operands for a URem, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyURemInst(Value *LHS, Value *RHS,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifyFRemInst - Given operands for an FRem, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyFRemInst(Value *LHS, Value *RHS,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifyShlInst - Given operands for a Shl, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifyLShrInst - Given operands for a LShr, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifyAShrInst - Given operands for a AShr, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifyAndInst - Given operands for an And, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyAndInst(Value *LHS, Value *RHS, const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifyOrInst - Given operands for an Or, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyOrInst(Value *LHS, Value *RHS, const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifyXorInst - Given operands for a Xor, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyXorInst(Value *LHS, Value *RHS, const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifySelectInst - Given operands for a SelectInst, see if we can fold
|
||||
/// the result. If not, this returns null.
|
||||
Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifyInsertValueInst - Given operands for an InsertValueInst, see if we
|
||||
/// can fold the result. If not, this returns null.
|
||||
@@ -201,13 +246,17 @@ namespace llvm {
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifyTruncInst - Given operands for an TruncInst, see if we can fold
|
||||
/// the result. If not, this returns null.
|
||||
Value *SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
//=== Helper functions for higher up the class hierarchy.
|
||||
|
||||
@@ -217,14 +266,18 @@ namespace llvm {
|
||||
Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// \brief Given a function and iterators over arguments, see if we can fold
|
||||
/// the result.
|
||||
@@ -233,7 +286,9 @@ namespace llvm {
|
||||
Value *SimplifyCall(Value *V, User::op_iterator ArgBegin,
|
||||
User::op_iterator ArgEnd, const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// \brief Given a function and set of arguments, see if we can fold the
|
||||
/// result.
|
||||
@@ -242,13 +297,16 @@ namespace llvm {
|
||||
Value *SimplifyCall(Value *V, ArrayRef<Value *> Args,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifyInstruction - See if we can compute a simplified version of this
|
||||
/// instruction. If not, this returns null.
|
||||
Value *SimplifyInstruction(Instruction *I, const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr);
|
||||
|
||||
|
||||
/// \brief Replace all uses of 'I' with 'SimpleV' and simplify the uses
|
||||
@@ -262,7 +320,8 @@ namespace llvm {
|
||||
bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr);
|
||||
|
||||
/// \brief Recursively attempt to simplify an instruction.
|
||||
///
|
||||
@@ -273,7 +332,8 @@ namespace llvm {
|
||||
bool recursivelySimplifyInstruction(Instruction *I,
|
||||
const DataLayout *TD = nullptr,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionTracker *AT = nullptr);
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
@@ -28,6 +28,7 @@ namespace llvm {
|
||||
class Instruction;
|
||||
class CallSite;
|
||||
class AliasAnalysis;
|
||||
class AssumptionTracker;
|
||||
class DataLayout;
|
||||
class MemoryDependenceAnalysis;
|
||||
class PredIteratorCache;
|
||||
@@ -325,6 +326,7 @@ namespace llvm {
|
||||
AliasAnalysis *AA;
|
||||
const DataLayout *DL;
|
||||
DominatorTree *DT;
|
||||
AssumptionTracker *AT;
|
||||
std::unique_ptr<PredIteratorCache> PredCache;
|
||||
|
||||
public:
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include "llvm/IR/Instruction.h"
|
||||
|
||||
namespace llvm {
|
||||
class AssumptionTracker;
|
||||
class DominatorTree;
|
||||
class DataLayout;
|
||||
class TargetLibraryInfo;
|
||||
@@ -41,12 +42,15 @@ class PHITransAddr {
|
||||
|
||||
/// TLI - The target library info if known, otherwise null.
|
||||
const TargetLibraryInfo *TLI;
|
||||
|
||||
/// A cache of @llvm.assume calls used by SimplifyInstruction.
|
||||
AssumptionTracker *AT;
|
||||
|
||||
/// InstInputs - The inputs for our symbolic address.
|
||||
SmallVector<Instruction*, 4> InstInputs;
|
||||
public:
|
||||
PHITransAddr(Value *addr, const DataLayout *DL)
|
||||
: Addr(addr), DL(DL), TLI(nullptr) {
|
||||
PHITransAddr(Value *addr, const DataLayout *DL, AssumptionTracker *AT)
|
||||
: Addr(addr), DL(DL), TLI(nullptr), AT(AT) {
|
||||
// If the address is an instruction, the whole thing is considered an input.
|
||||
if (Instruction *I = dyn_cast<Instruction>(Addr))
|
||||
InstInputs.push_back(I);
|
||||
|
@@ -35,6 +35,7 @@
|
||||
|
||||
namespace llvm {
|
||||
class APInt;
|
||||
class AssumptionTracker;
|
||||
class Constant;
|
||||
class ConstantInt;
|
||||
class DominatorTree;
|
||||
@@ -221,6 +222,9 @@ namespace llvm {
|
||||
///
|
||||
Function *F;
|
||||
|
||||
/// The tracker for @llvm.assume intrinsics in this function.
|
||||
AssumptionTracker *AT;
|
||||
|
||||
/// LI - The loop information for the function we are currently analyzing.
|
||||
///
|
||||
LoopInfo *LI;
|
||||
|
@@ -25,6 +25,8 @@ namespace llvm {
|
||||
class DataLayout;
|
||||
class StringRef;
|
||||
class MDNode;
|
||||
class AssumptionTracker;
|
||||
class DominatorTree;
|
||||
class TargetLibraryInfo;
|
||||
|
||||
/// Determine which bits of V are known to be either zero or one and return
|
||||
@@ -36,7 +38,10 @@ namespace llvm {
|
||||
/// same width as the vector element, and the bit is set only if it is true
|
||||
/// for all of the elements in the vector.
|
||||
void computeKnownBits(Value *V, APInt &KnownZero, APInt &KnownOne,
|
||||
const DataLayout *TD = nullptr, unsigned Depth = 0);
|
||||
const DataLayout *TD = nullptr, unsigned Depth = 0,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
/// Compute known bits from the range metadata.
|
||||
/// \p KnownZero the set of bits that are known to be zero
|
||||
void computeKnownBitsFromRangeMetadata(const MDNode &Ranges,
|
||||
@@ -45,21 +50,29 @@ namespace llvm {
|
||||
/// ComputeSignBit - Determine whether the sign bit is known to be zero or
|
||||
/// one. Convenience wrapper around computeKnownBits.
|
||||
void ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne,
|
||||
const DataLayout *TD = nullptr, unsigned Depth = 0);
|
||||
const DataLayout *TD = nullptr, unsigned Depth = 0,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
/// isKnownToBeAPowerOfTwo - Return true if the given value is known to have
|
||||
/// exactly one bit set when defined. For vectors return true if every
|
||||
/// element is known to be a power of two when defined. Supports values with
|
||||
/// integer or pointer type and vectors of integers. If 'OrZero' is set then
|
||||
/// returns true if the given value is either a power of two or zero.
|
||||
bool isKnownToBeAPowerOfTwo(Value *V, bool OrZero = false, unsigned Depth = 0);
|
||||
bool isKnownToBeAPowerOfTwo(Value *V, bool OrZero = false, unsigned Depth = 0,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
/// isKnownNonZero - Return true if the given value is known to be non-zero
|
||||
/// when defined. For vectors return true if every element is known to be
|
||||
/// non-zero when defined. Supports values with integer or pointer type and
|
||||
/// vectors of integers.
|
||||
bool isKnownNonZero(Value *V, const DataLayout *TD = nullptr,
|
||||
unsigned Depth = 0);
|
||||
unsigned Depth = 0, AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use
|
||||
/// this predicate to simplify operations downstream. Mask is known to be
|
||||
@@ -71,7 +84,10 @@ namespace llvm {
|
||||
/// same width as the vector element, and the bit is set only if it is true
|
||||
/// for all of the elements in the vector.
|
||||
bool MaskedValueIsZero(Value *V, const APInt &Mask,
|
||||
const DataLayout *TD = nullptr, unsigned Depth = 0);
|
||||
const DataLayout *TD = nullptr, unsigned Depth = 0,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
|
||||
/// ComputeNumSignBits - Return the number of times the sign bit of the
|
||||
@@ -83,7 +99,10 @@ namespace llvm {
|
||||
/// 'Op' must have a scalar integer type.
|
||||
///
|
||||
unsigned ComputeNumSignBits(Value *Op, const DataLayout *TD = nullptr,
|
||||
unsigned Depth = 0);
|
||||
unsigned Depth = 0,
|
||||
AssumptionTracker *AT = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
/// ComputeMultiple - This function computes the integer multiple of Base that
|
||||
/// equals V. If successful, it returns true and returns the multiple in
|
||||
@@ -191,6 +210,13 @@ namespace llvm {
|
||||
/// and byval arguments.
|
||||
bool isKnownNonNull(const Value *V, const TargetLibraryInfo *TLI = nullptr);
|
||||
|
||||
/// Return true if it is valid to use the assumptions provided by an
|
||||
/// assume intrinsic, I, at the point in the control-flow identified by the
|
||||
/// context instruction, CxtI.
|
||||
bool isValidAssumeForContext(const Instruction *I, const Instruction *CxtI,
|
||||
const DataLayout *DL = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user