diff options
author | Hal Finkel <hfinkel@anl.gov> | 2014-07-18 15:51:28 +0000 |
---|---|---|
committer | Hal Finkel <hfinkel@anl.gov> | 2014-07-18 15:51:28 +0000 |
commit | b0407ba0716d940d035f5da73f6d3bfbaffecb44 (patch) | |
tree | 0fb08700ec2601986a9f5195a9d57fb6e0b48444 /llvm/lib/IR/Value.cpp | |
parent | 9cf7ac75893c9f83099ce59dd4fd5d1ba7ead25a (diff) | |
download | llvm-b0407ba0716d940d035f5da73f6d3bfbaffecb44.zip llvm-b0407ba0716d940d035f5da73f6d3bfbaffecb44.tar.gz llvm-b0407ba0716d940d035f5da73f6d3bfbaffecb44.tar.bz2 |
Add a dereferenceable attribute
This attribute indicates that the parameter or return pointer is
dereferenceable. Practically speaking, loads from such a pointer within the
associated byte range are safe to speculatively execute. Such pointer
parameters are common in source languages (C++ references, for example).
llvm-svn: 213385
Diffstat (limited to 'llvm/lib/IR/Value.cpp')
-rw-r--r-- | llvm/lib/IR/Value.cpp | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp index 999685e..efdd6a7 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -15,6 +15,7 @@ #include "LLVMContextImpl.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" +#include "llvm/IR/CallSite.h" #include "llvm/IR/Constant.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" @@ -504,9 +505,29 @@ static bool isDereferenceablePointer(const Value *V, const DataLayout *DL, if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) return !GV->hasExternalWeakLinkage(); - // byval arguments are ok. - if (const Argument *A = dyn_cast<Argument>(V)) - return A->hasByValAttr(); + // byval arguments are okay. Arguments specifically marked as + // dereferenceable are okay too. + if (const Argument *A = dyn_cast<Argument>(V)) { + if (A->hasByValAttr()) + return true; + else if (uint64_t Bytes = A->getDereferenceableBytes()) { + Type *Ty = V->getType()->getPointerElementType(); + if (Ty->isSized() && DL && DL->getTypeStoreSize(Ty) <= Bytes) + return true; + } + + return false; + } + + // Return values from call sites specifically marked as dereferenceable are + // also okay. + if (ImmutableCallSite CS = V) { + if (uint64_t Bytes = CS.getDereferenceableBytes(0)) { + Type *Ty = V->getType()->getPointerElementType(); + if (Ty->isSized() && DL && DL->getTypeStoreSize(Ty) <= Bytes) + return true; + } + } // For GEPs, determine if the indexing lands within the allocated object. if (const GEPOperator *GEP = dyn_cast<GEPOperator>(V)) { |